<template>
  <div class="deviceviewbox" v-loading="syncLoading">
    <div class="treebox">
      <el-descriptions :colon="false" title="设备管理目录" size="medium">
        <el-descriptions-item class="devdescript">
          <el-input
            style="width: 10vw"
            v-model="filterText"
            placeholder="搜索工厂、工序、设备"
            suffix-icon="el-icon-search"
            clearable
          ></el-input>
          <el-button v-show="!syncType" type="text" @click="syncFunc"
            >同步设备</el-button
          >
        </el-descriptions-item>
      </el-descriptions>
      <!-- 左侧目录树 -->
      <el-tree
        class="tree-flex-col"
        :data="treeData"
        :props="props"
        node-key="Guid"
        :highlight-current="true"
        :default-expanded-keys="[expandedKey]"
        :default-checked-keys="[defaultCheckedKeys]"
        accordion
        @node-contextmenu="onContextmenu"
        @node-click="clickNode"
        ref="tree"
        :filter-node-method="filterNode"
      >
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <!-- 搜索值高亮 -->
          <div style="display: flex; align-items: center; flex: auto">
            <i
              style="margin-right: 7px"
              :class="titleIcon(data, devIconData)"
            ></i>
            <div
              style="display: flex"
              v-if="node.label.indexOf(filterText) > -1"
            >
              {{ node.label.substr(0, node.label.indexOf(filterText)) }}
              <span style="color: #f50">{{ filterText }}</span>
              {{
                node.label.substr(
                  node.label.indexOf(filterText) + filterText.length
                )
              }}
            </div>
            <span v-else>{{ node.label }}</span>
          </div>
        </span>
      </el-tree>
    </div>
    <!-- 右侧上方信息展示 -->
    <div class="treemain" v-show="treeData.length == 0"></div>
    <div class="treemain" v-show="treeData.length > 0">
      <el-card class="top-card" v-show="cardVisable.all">
        <el-descriptions title="项目信息" size="medium">
          <el-descriptions-item label="项目名称">{{
            programName
          }}</el-descriptions-item>
        </el-descriptions>
      </el-card>
      <el-card class="top-card" v-show="cardVisable.line">
        <!-- <el-descriptions title="产线信息" size="medium">
          <el-descriptions-item label="产线名称">{{
            lineName
          }}</el-descriptions-item>
        </el-descriptions> -->
      </el-card>
      <el-card class="top-card" v-show="cardVisable.process">
        <!-- <el-descriptions title="工序信息" size="medium">
          <el-descriptions-item label="工序名称">{{
            processName
          }}</el-descriptions-item>
        </el-descriptions> -->
      </el-card>
      <el-card class="top-card" v-show="cardVisable.equ">
        <el-descriptions title="设备信息" size="medium">
          <el-descriptions-item label="设备名称">{{
            equName
          }}</el-descriptions-item>
          <el-descriptions-item label="设备编码">{{
            equCode
          }}</el-descriptions-item>
          <!-- <el-descriptions-item label="设备分类">{{
            equCategory
          }}</el-descriptions-item> -->
        </el-descriptions>
      </el-card>
      <PlcMsgCard
        :plcmsg="plcmsg"
        :networkConfig="networkConfig"
        :connectionId="connectionId"
        v-show="cardVisable.plc"
      ></PlcMsgCard>
      <!-- 右侧采集变量信息展示 -->
      <PlcVarTable
        ref="plcVarTable"
        class="flex-col"
        :node="nowNode.data"
        v-show="cardVisable.plc"
      ></PlcVarTable>
      <el-card
        class="flex-col"
        v-show="cardVisable.isLineOrProcess"
        body-style="display: flex;  flex-direction: column;  flex: 1; overflow: hidden;"
      >
      </el-card>
      <!-- 设备和项目变量卡片展示 -->
      <el-card
        class="flex-col"
        v-show="!cardVisable.plc && !cardVisable.isLineOrProcess"
        body-style="display: flex;  flex-direction: column;  flex: 1; overflow: hidden;"
      >
        <el-descriptions
          :title="varType == 1 ? '设备内部变量' : '项目变量'"
          size="medium"
        ></el-descriptions>
        <el-form :inline="true">
          <el-form-item label="变量名:"
            ><el-input placeholder="请输入" v-model="alias"></el-input
          ></el-form-item>
          <el-form-item label="变量类型:">
            <el-select placeholder="请选择" v-model="dataTypeId">
              <el-option
                v-for="item in variableOption"
                :key="item.name"
                :label="item.name"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="数据保存:">
            <el-select placeholder="请选择" v-model="isPowerSave">
              <el-option key="0" label="全部" :value="0"></el-option>
              <el-option key="1" label="断电释放" :value="1"></el-option>
              <el-option key="2" label="断电保持" :value="2"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="监控状态:">
            <el-select placeholder="请选择" v-model="isMonitor">
              <el-option key="0" label="全部" :value="0"></el-option>
              <el-option key="1" label="未监控" :value="1"></el-option>
              <el-option key="2" label="监控" :value="2"></el-option>
            </el-select>
          </el-form-item>

          <el-form-item>
            <el-button type="primary" @click="selectGlobleVar()"
              >搜索</el-button
            >
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="addVarFunc">添加</el-button>
          </el-form-item>

          <el-form-item>
            <el-button
              :disabled="!importBtnVisable"
              type="primary"
              @click="
                openCSV(nowNode.data.StructGuid, nowNode.data.DisplayName)
              "
              >导出</el-button
            >
          </el-form-item>
          <el-form-item>
            <el-button
              type="primary"
              :disabled="!importBtnVisable"
              @click="
                () => {
                  importVisable = true;
                  importType = 'all';
                  importBtn = false;
                  fileList = [];
                }
              "
              >导入</el-button
            >
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="DeleteAllVar()">删除</el-button>
          </el-form-item>
          <el-form-item>
            <el-button
              type="warning"
              @click="
                () => {
                  monitoredForm = {
                    Title: '',
                    scanPeriod: 1,
                    isMonitored: true,
                  };
                  $confirm(
                    `此操作加入监控
                      , 是否继续?`,
                    '提示',
                    {
                      confirmButtonText: '确定',
                      cancelButtonText: '取消',
                      type: 'warning',
                    }
                  ).then(() => {
                    if (this.globalType == 2) {
                      if (
                        this.fahtherCheckedAll.length == 0 &&
                        this.sonCheckedAllSelected.length === 0
                      ) {
                        this.$message.error('请至少选中一个节点');
                        return;
                      }
                    }
                    if (this.globalType == 1) {
                      if (
                        this.fahtherCheckedEqu.length == 0 &&
                        this.sonCheckedEquSelected.length === 0
                      ) {
                        this.$message.error('请至少选中一个节点');
                        return;
                      }
                    }
                    monitoredForm.Title = '加入监控';
                    alladdMonitoredVisable = true;
                  });
                }
              "
              >加入监控</el-button
            >
          </el-form-item>
          <el-form-item>
            <el-button
              type="warning"
              @click="
                () => {
                  monitoredForm = {
                    Title: '',
                    scanPeriod: 1,
                    isMonitored: false,
                  };
                  $confirm(
                    `此操作取消监控
                      , 是否继续?`,
                    '提示',
                    {
                      confirmButtonText: '确定',
                      cancelButtonText: '取消',
                      type: 'warning',
                    }
                  ).then(() => {
                    // if (this.fahtherCheckedAll.length == 0 && this.sonCheckedAllSelected.length == 0) {
                    //   this.$message.error('至少选择一个变量')
                    //   return;
                    // }
                    monitoredForm.Title = '取消监控';
                    AllAddMonitored(monitoredForm);
                  });
                }
              "
              >取消监控</el-button
            >
          </el-form-item>
        </el-form>
        <!-- 详细信息表格 -->
        <el-table
          :row-class-name="getRowClass"
          show-checkbox
          :virtual-scroll="true"
          :item-size="50"
          row-key="Alias"
          width="100%"
          height="100%"
          ref="multipleTable"
          :data="globalTable"
          tooltip-effect="dark"
          :highlight-current-row="true"
          style="flex: 1"
          :expand-row-keys="expandedRowKeys"
          @select="checkedBoxHandler"
          @select-all="fatherSelectAllHandler"
          @expand-change="
            (row, expandedRows) => {
              expandValue(row, expandedRows);
            }
          "
        >
          <el-table-column type="selection" width="55"></el-table-column>
          <!-- 树形内嵌表格 -->
          <el-table-column type="expand">
            <template slot-scope="props" v-if="props.row.IsArray">
              <div style="height: 400px">
                <el-table
                  v-loading="expandLoading"
                  row-key="Alias"
                  :ref="'sontable' + props.row.ID"
                  style="width: 100%"
                  :data="
                    getRowExpandData(
                      props.row.ID,
                      globalType,
                      sonCheckedAll,
                      sonCheckedEqu
                    )
                  "
                  :show-header="true"
                  height="100%"
                  max-height="400px"
                  @selection-change="sonHandleSelectionChange"
                >
                  <el-table-column
                    type="selection"
                    width="55"
                  ></el-table-column>
                  <el-table-column width="100"></el-table-column>
                  <el-table-column
                    prop="Alias"
                    label="变量名"
                    show-overflow-tooltip
                  >
                  </el-table-column>
                  <!-- <el-table-column
                    prop="DataName"
                    label="变量地址"
                    show-overflow-tooltip
                  >
                  </el-table-column> -->
                  <el-table-column prop="DataType" label="变量类型" width="100">
                    <template slot-scope="scope">
                      <span>{{ dataToPlc(scope.row.DataType) }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="Description"
                    label="变量描述"
                    show-overflow-tooltip
                  >
                  </el-table-column>
                  <el-table-column
                    prop="IsPersistence"
                    label="数据保存"
                    show-overflow-tooltip
                  >
                    <template slot-scope="scope">
                      <span>{{
                        scope.row.IsPersistence ? "断电保持" : "断电释放"
                      }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="InitValue"
                    label="初始值"
                    show-overflow-tooltip
                  >
                  </el-table-column>
                  <!-- <el-table-column prop="IsArray" label="是否数组" width="100">
                    <template slot-scope="scope">
                      <span></span>
                    </template>
                  </el-table-column>
                  <el-table-column prop="ArrayLength" label="数组长度">
                    <template slot-scope="scope">
                      <span></span> 
                    </template>
                  </el-table-column> -->
                  <el-table-column
                    prop="IsMonitored"
                    label="监控状态"
                    width="120"
                  >
                    <template slot-scope="scope">
                      <span v-if="!scope.row.IsArray">{{
                        scope.row.IsMonitored ? "是" : "否"
                      }}</span>
                      <span v-else>-</span>
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="ScanPeriod"
                    label="扫描周期(ms)"
                    show-overflow-tooltip
                  >
                    <template slot-scope="scope">
                      <span>{{
                        scope.row.IsArray
                          ? "-"
                          : displayScanPeriod(scope.row.ScanPeriod)
                      }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="操作" width="200">
                    <template slot-scope="scope">
                      <!-- <el-button
                        v-show="scope.row.IsArray != null"
                        type="text"
                        @click="
                          () => {
                            var param = scope.row;
                            globleForm = {
                              Url: '',
                              Title: '',
                              id: param.ID,
                              isArray: param.IsArray,
                              arrayLength: param.ArrayLength,
                              eqId: varType == 1 ? nowNode.data.StructGuid : 0,
                              alias: param.Alias,
                              name: param.DataName,
                              isMonitored: param.isMonitored,
                              dataTypeId: param.DataType,
                              valueType: param.ValueType,
                              description: param.Description,
                              isPersistence: param.IsPersistence,
                              initValue: param.InitValue,
                            };
                            globleForm.Url = '/EqManage/UpdateEqGlobalVarInfo';
                            globleForm.Title = '修改数据';
                            globleVarVisable = true;
                          }
                        "
                        >修改</el-button
                      > -->
                      <!-- <el-button
                        v-show="scope.row.IsArray != null"
                        type="text"
                        @click="
                          () => {
                            var param = scope.row;
                            globleForm = {
                              Url: '',
                              Title: '',
                              id: param.ID,
                              isArray: param.IsArray,
                              arrayLength: param.ArrayLength,
                              eqId: varType == 1 ? nowNode.data.StructGuid : 0,
                              alias: param.Alias,
                              name: param.DataName,
                              isMonitored: param.isMonitored,
                              dataTypeId: param.DataType,
                              valueType: param.ValueType,
                              description: param.Description,
                              isPersistence: param.IsPersistence,
                              initValue: param.InitValue,
                            };
                            globleForm.Url = '/EqManage/DeleteEqGlobalVar';
                            globleForm.Title = '删除数据';
                            $confirm(`此操作删除数据, 是否继续?`, '提示', {
                              confirmButtonText: '确定',
                              cancelButtonText: '取消',
                              type: 'warning',
                            })
                              .then(() => {
                                DeleteglobalVarOperate(globleForm);
                              })
                              .catch((err) => {
                                $message({
                                  type: 'info',
                                  message: `已取消删除数据,${err}`,
                                });
                              });
                            // globalVarOperate(globleForm)
                          }
                        "
                        >删除</el-button
                      > -->
                      <el-button
                        v-show="scope.row.IsArray == false"
                        type="text"
                        @click="
                          () => {
                            var param = scope.row;

                            $confirm(
                              `此操作${
                                param.IsMonitored ? '取消监控' : '加入监控'
                              }, 是否继续?`,
                              '提示',
                              {
                                confirmButtonText: '确定',
                                cancelButtonText: '取消',
                                type: 'warning',
                              }
                            )
                              .then(() => {
                                monitoredForm = {
                                  Alias: param.Alias.split('[')[0],
                                  Update: false,
                                  Url: '',
                                  id: param.ID,
                                  index: 0,
                                  scanPeriod: param.ScanPeriod
                                    ? param.ScanPeriod
                                    : 1,
                                  desc: param.Description,
                                  initValue: param.InitValue,
                                  isMonitored: !param.IsMonitored,
                                };

                                monitoredForm.Url =
                                  '/EqManage/UpdateEqGloVarMonitor';
                                monitoredForm.Title = param.IsMonitored
                                  ? '取消监控'
                                  : '加入监控';
                                if (param.IsMonitored) {
                                  addMonitored(monitoredForm);
                                } else {
                                  addMonitoredVisable = true;
                                }
                              })
                              .catch((error) => {
                                $message({
                                  type: 'info',
                                  message: `已取消操作,${error}`,
                                });
                              });
                          }
                        "
                        >{{
                          scope.row.IsMonitored ? "取消监控" : "加入监控"
                        }}</el-button
                      >
                      <el-button
                        type="text"
                        v-show="scope.row.IsArray == null"
                        @click="
                          () => {
                            arrayUpdateForm = {
                              Update: true,
                              Title: '修改数组描述',
                              Url: '/EqManage/UpdateEqGloArrayDesc',
                              alias: scope.row.Alias,
                              id: scope.row.ParentId,
                              desc: scope.row.Description,
                              index: parseInt(
                                scope.row.Alias.match(/\[(.*?)\]/)[1]
                              ),
                              initValue: scope.row.InitValue,
                            };
                            arrayUpdateVisable = true;
                          }
                        "
                        >修改</el-button
                      >
                      <el-button
                        v-show="scope.row.IsArray == null"
                        type="text"
                        @click="
                          () => {
                            var param = scope.row;
                            testConsole(param);
                            $confirm(
                              `此操作${
                                param.IsMonitored ? '取消监控' : '加入监控'
                              }, 是否继续?`,
                              '提示',
                              {
                                confirmButtonText: '确定',
                                cancelButtonText: '取消',
                                type: 'warning',
                              }
                            )
                              .then(() => {
                                monitoredForm = {
                                  Alias: param.Alias.split('[')[0],
                                  Update: true,
                                  Url: '',
                                  id: param.ParentId,
                                  index: parseInt(
                                    param.Alias.match(/\[(.*?)\]/)[1]
                                  ),
                                  scanPeriod: param.ScanPeriod
                                    ? param.ScanPeriod
                                    : 1,
                                  desc: param.Description,
                                  initValue: param.InitValue,
                                  isMonitored: !param.IsMonitored,
                                };

                                monitoredForm.Url =
                                  '/EqManage/UpdateEqGloVarMonitor';
                                monitoredForm.Title = param.IsMonitored
                                  ? '取消监控'
                                  : '加入监控';
                                //addMonitored(monitoredForm);
                                if (param.IsMonitored) {
                                  addMonitored(monitoredForm);
                                } else {
                                  addMonitoredVisable = true;
                                }
                              })
                              .catch((error) => {
                                $message({
                                  type: 'info',
                                  message: `已取消操作,${error}`,
                                });
                              });
                          }
                        "
                        >{{
                          scope.row.IsMonitored ? "取消监控" : "加入监控"
                        }}</el-button
                      >
                    </template>
                  </el-table-column>
                </el-table>
                <el-pagination
                  style="position: relative; width: 100%"
                  background
                  layout="->,total,prev, pager, next,jumper"
                  v-if="sonTotal > 0"
                  :total="sonTotal"
                  :current-page.sync="sonPageNum"
                  @current-change="handleCurrentChange"
                >
                </el-pagination>
              </div>
            </template>
          </el-table-column>
          <el-table-column
            type="index"
            label="序号"
            show-overflow-tooltip
            :index="table_index"
          >
          </el-table-column>
          <el-table-column prop="Alias" label="变量名" show-overflow-tooltip>
          </el-table-column>
          <!-- <el-table-column
            prop="DataName"
            label="变量地址"
            show-overflow-tooltip
          >
          </el-table-column> -->
          <el-table-column prop="DataType" label="变量类型" width="100">
            <template slot-scope="scope">
              <span>{{ dataToPlc(scope.row.DataType) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            prop="Description"
            label="变量描述"
            show-overflow-tooltip
          >
          </el-table-column>
          <el-table-column
            prop="IsPersistence"
            label="数据保存"
            show-overflow-tooltip
          >
            <template slot-scope="scope">
              <span>{{
                scope.row.IsPersistence ? "断电保持" : "断电释放"
              }}</span>
            </template>
          </el-table-column>
          <el-table-column
            prop="InitValue"
            label="初始值"
            show-overflow-tooltip
          >
          </el-table-column>
          <!-- <el-table-column prop="IsArray" label="是否数组" width="100">
            <template slot-scope="scope">
              <span>{{ scope.row.IsArray ? "一维数组" : "标量变量" }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="ArrayLength" label="数组长度">
            <template slot-scope="scope">
              <span v-if="scope.row.IsArray">{{ scope.row.ArrayLength }}</span>
              <span v-else>-</span>
            </template>
          </el-table-column> -->
          <el-table-column prop="IsMonitored" label="监控状态" width="120">
            <template slot-scope="scope">
              <span v-if="!scope.row.IsArray">{{
                scope.row.IsMonitored ? "是" : "否"
              }}</span>
              <span v-else>-</span>
            </template>
          </el-table-column>
          <el-table-column
            prop="ScanPeriod"
            label="扫描周期(ms)"
            show-overflow-tooltip
            width="100"
          >
            <template slot-scope="scope">
              <span>{{
                scope.row.IsArray
                  ? "-"
                  : displayScanPeriod(scope.row.ScanPeriod)
              }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="250">
            <template slot-scope="scope">
              <el-button
                v-show="scope.row.IsArray != null"
                type="text"
                @click="
                  () => {
                    updateVarFunc(scope);
                  }
                "
                >修改</el-button
              >
              <el-button
                v-show="scope.row.IsArray != null"
                type="text"
                @click="
                  () => {
                    var param = scope.row;
                    globleForm = {
                      Url: '',
                      Title: '',
                      id: param.ID,
                      isArray: param.IsArray,
                      arrayLength: param.ArrayLength,
                      eqId: varType == 1 ? nowNode.data.StructGuid : 0,
                      alias: param.Alias,
                      name: param.DataName,
                      isMonitored: param.isMonitored,
                      dataTypeId: param.DataType,
                      valueType: param.ValueType,
                      description: param.Description,
                      isPersistence: param.IsPersistence,
                      initValue: param.InitValue,
                    };
                    globleForm.Url = '/EqManage/DeleteEqGlobalVar';
                    globleForm.Title = '删除数据';
                    $confirm(`此操作删除数据, 是否继续?`, '提示', {
                      confirmButtonText: '确定',
                      cancelButtonText: '取消',
                      type: 'warning',
                    })
                      .then(() => {
                        DeleteglobalVarOperate(globleForm);
                      })
                      .catch((err) => {
                        $message({
                          type: 'info',
                          message: `已取消删除数据,${err}`,
                        });
                      });
                    // globalVarOperate(globleForm)
                  }
                "
                >删除</el-button
              >

              <el-button
                v-if="scope.row.IsArray == false"
                type="text"
                @click="
                  () => {
                    var param = scope.row;
                    testConsole(param);
                    $confirm(
                      `此操作${
                        param.IsMonitored ? '取消监控' : '加入监控'
                      }, 是否继续?`,
                      '提示',
                      {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                      }
                    )
                      .then(() => {
                        monitoredForm = {
                          Alias: param.Alias.split('[')[0],
                          Update: false,
                          Url: '',
                          id: param.ID,
                          index: 0,
                          scanPeriod: param.ScanPeriod ? param.ScanPeriod : 1,
                          desc: param.Description,
                          initValue: param.InitValue,
                          isMonitored: !param.IsMonitored,
                        };

                        monitoredForm.Url = '/EqManage/UpdateEqGloVarMonitor';
                        monitoredForm.Title = param.IsMonitored
                          ? '取消监控'
                          : '加入监控';
                        if (param.IsMonitored) {
                          addMonitored(monitoredForm);
                        } else {
                          addMonitoredVisable = true;
                        }
                      })
                      .catch((error) => {
                        $message({
                          type: 'info',
                          message: `已取消操作,${error}`,
                        });
                      });
                  }
                "
                >{{
                  scope.row.IsMonitored ? "取消监控" : "加入监控"
                }}</el-button
              >
              <el-button
                type="text"
                v-show="scope.row.IsArray == null"
                @click="
                  () => {
                    this.testConsole(scope.row);
                    arrayUpdateForm = {
                      Update: true,
                      Title: '修改数组描述',
                      Url: '/EqManage/UpdateEqGloArrayDesc',
                      alias: scope.row.Alias,
                      id: scope.row.ParentId,
                      desc: scope.row.Description,
                      index: parseInt(scope.row.Alias.match(/\[(.*?)\]/)[1]),
                      initValue: scope.row.InitValue,
                    };
                    arrayUpdateVisable = true;
                  }
                "
                >修改</el-button
              >
              <el-button
                v-show="scope.row.IsArray == null"
                type="text"
                @click="
                  () => {
                    var param = scope.row;
                    $confirm(
                      `此操作${
                        param.IsMonitored ? '取消监控' : '加入监控'
                      }, 是否继续?`,
                      '提示',
                      {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                      }
                    )
                      .then(() => {
                        monitoredForm = {
                          Alias: param.Alias.split('[')[0],
                          Update: true,
                          Url: '',
                          id: param.ParentId,
                          index: parseInt(param.Alias.match(/\[(.*?)\]/)[1]),
                          scanPeriod: param.ScanPeriod ? param.ScanPeriod : 1,
                          desc: param.Description,
                          initValue: param.InitValue,
                          isMonitored: !param.IsMonitored,
                        };

                        monitoredForm.Url = '/EqManage/UpdateEqGloVarMonitor';
                        monitoredForm.Title = param.IsMonitored
                          ? '取消监控'
                          : '加入监控';
                        //addMonitored(monitoredForm);
                        if (param.IsMonitored) {
                          addMonitored(monitoredForm);
                        } else {
                          addMonitoredVisable = true;
                        }
                      })
                      .catch((error) => {
                        $message({
                          type: 'info',
                          message: `已取消操作,${error}`,
                        });
                      });
                  }
                "
                >{{
                  scope.row.IsMonitored ? "取消监控" : "加入监控"
                }}</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          background
          v-if="total > 0"
          layout="->,total,sizes,prev, pager, next,jumper"
          :total="total"
          :current-page.sync="pageNum"
          :page-sizes="[20, 40, 60, 100]"
          :page-size="pageSize"
          @size-change="handleSizeChange"
          @current-change="CurrentChange"
        >
        </el-pagination>
      </el-card>
    </div>
    <!-- 修改和添加设备弹窗 -->
    <el-dialog
      destroy-on-close
      :visible.sync="addLineVisable"
      width="30%"
      @open="openDialog('lineForm')"
    >
      <span slot="title" style="text-align: center"
        >{{ lineForm.Title }}
        <el-divider></el-divider>
      </span>
      <el-form
        :model="lineForm"
        ref="lineForm"
        :rules="rules"
        label-width="200px"
      >
        <el-form-item
          v-if="dialogVisable.name"
          :label="lineForm.NameLabel"
          prop="Name"
          :rules="[
            {
              required: true,
              message: `${lineForm.NameLabel}不能为空`,
              trigger: 'blur',
            },
          ]"
        >
          <el-input
            v-model="lineForm.Name"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item
          v-if="factoryCodeVisable"
          :label="lineForm.CodeLabel"
          prop="Code"
          :rules="[
            {
              required: true,
              message: `${lineForm.CodeLabel}不能为空`,
              trigger: 'blur',
            },
          ]"
        >
          <el-input
            v-model="lineForm.Code"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item
          prop="Equipindex"
          v-if="dialogVisable.level"
          label="设备分类"
        >
          <el-select v-model="lineForm.Equipindex" placeholder="请选择">
            <el-option
              v-for="(item, index) in deviceOption"
              :key="index"
              :label="item.name"
              :value="index"
            >
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              {
                addLineVisable = false;
                closeLineForm();
              }
            "
            >取 消</el-button
          >
          <el-button
            type="primary"
            @click="
              () => {
                addLine(lineForm);
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <!-- 添加部件弹窗 -->
    <el-dialog
      @open="openDialog('partFormRef')"
      :destroy-on-close="true"
      :visible.sync="plcSettingVisable"
      width="600px"
    >
      <span slot="title" style="text-align: center"
        >{{ plcForm.Title }}
        <el-divider></el-divider>
      </span>
      <el-form
        ref="partFormRef"
        :model="plcForm"
        :rules="plcRules"
        :validate-on-rule-change="false"
        label-width="230px"
      >
        <el-form-item label="部件名称" prop="Name">
          <el-input
            v-model="plcForm.Name"
            style="width: 280px"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="通讯类型" prop="CommunicationType">
          <el-select
            style="width: 280px"
            v-model="plcForm.CommunicationType"
            placeholder="请选择通讯类型"
          >
            <el-option label="OPCUA" :value="6"></el-option>
            <!-- <el-option label="欧姆龙" :value="1"></el-option> -->
            <el-option label="Modbus" :value="7"></el-option>
            <el-option label="GEM" :value="8"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          v-for="(item, index) in networkConfig.slice(0, 1)"
          :label="item.name"
          :key="index"
          :prop="'networkConfig' + index"
        >
          <div style="display: flex; margin-bottom: -10px">
            <el-form-item :prop="'IP' + index">
              <el-input
                required
                v-model="item.IP"
                style="width: 200px"
                autocomplete="off"
                placeholder="请输入IP"
              >
                <!-- <template v-if="plcForm.CommunicationType == 6" slot="prepend"
              ><span style="width:30px">opc.tcp://</span></template
            > -->
              </el-input>
            </el-form-item>

            <el-form-item :prop="'Port' + index">
              <el-input
                required
                v-model.trim="item.Port"
                style="width: 80px"
                autocomplete="off"
                placeholder="端口号"
              ></el-input>
            </el-form-item>
          </div>
        </el-form-item>
        <el-form-item
          v-for="(item, index) in networkConfig.slice(1)"
          :label="item.name"
          :key="'networkConfig' + (index + 1)"
        >
          <div style="display: flex; margin-bottom: -10px">
            <el-form-item :prop="'IP' + (index + 1)">
              <el-input
                v-model="item.IP"
                style="width: 200px"
                autocomplete="off"
                placeholder="请输入IP"
              >
                <!-- <template v-if="plcForm.CommunicationType == 6" slot="prepend"
              ><span style="width:30px">opc.tcp://</span></template
            > -->
              </el-input>
            </el-form-item>

            <el-form-item :prop="'Port' + (index + 1)">
              <el-input
                v-model.trim="item.Port"
                style="width: 80px"
                autocomplete="off"
                placeholder="端口号"
              ></el-input>
            </el-form-item>
          </div>
        </el-form-item>
        <!-- 这部分是modbus专用 -->
        <el-form-item
          label="站号"
          prop="Site"
          v-if="plcForm.CommunicationType == 7"
          :rules="[
            { required: true, message: '站号不可为空' },
            {
              pattern: /^[1-9]\d*$/,
              message: '只可以输入正整数',
              trigger: 'change',
            },
          ]"
        >
          <el-input
            v-model.trim="plcForm.Site"
            style="width: 280px"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item
          label="首地址从0开始"
          v-show="plcForm.CommunicationType == 7"
        >
          <el-checkbox v-model="plcForm.ZeroStart"></el-checkbox>
        </el-form-item>
        <el-form-item
          label="浮点转换规则"
          v-show="plcForm.CommunicationType == 7"
        >
          <el-select
            v-model="plcForm.FloatRule"
            :clearable="false"
            style="width: 280px"
            autocomplete="off"
          >
            <el-option label="ABCD" value="ABCD"></el-option>
            <el-option label="BADC" value="BADC"></el-option>
            <el-option label="CDAB" value="CDAB"></el-option>
            <el-option label="DCBA" value="DCBA"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          label="字符串颠倒"
          v-show="plcForm.CommunicationType == 7"
        >
          <el-checkbox v-model="plcForm.StringReverse"></el-checkbox>
        </el-form-item>
        <el-form-item
          label="检测消息号一致"
          v-show="plcForm.CommunicationType == 7"
        >
          <el-checkbox v-model="plcForm.MessageConsist"></el-checkbox>
        </el-form-item>
        <el-form-item label="用户名">
          <el-input
            v-model="plcForm.UserName"
            style="width: 280px"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="密码">
          <el-input
            v-model="plcForm.Password"
            style="width: 280px"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="超时时间(ms)" prop="TimeOut">
          <el-input
            v-model="plcForm.TimeOut"
            style="width: 280px"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <!-- <el-form-item label="掉线判断阈值(ms)" prop="MaxDisconnection">
          <el-input
            v-model="plcForm.MaxDisconnection"
            style="width: 280px"
            autocomplete="off"
          ></el-input>
        </el-form-item> -->
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button @click="plcSettingVisable = false">取 消</el-button>
          <el-button
            type="primary"
            @click="
              () => {
                operatePlc(plcForm);
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <!-- 添加和修改项目变量弹窗 -->
    <el-dialog destroy-on-close :visible.sync="variableVisable" width="30%">
      <span slot="title" style="text-align: center"
        >{{ variableForm.Title }}
        <el-divider></el-divider>
      </span>
      <el-form :model="variableForm" label-width="200px">
        <el-form-item label="变量名">
          <el-input
            v-model="variableForm.Alias"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="数据类型">
          <el-select
            style="width: 50%"
            v-model="variableForm.DataTypeId"
            placeholder="请选择数据类型"
          >
            <el-option
              v-for="item in variableType"
              :key="item.name"
              :label="item.name"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="变量地址" prop="IP">
          <el-input
            v-model="variableForm.Name"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="是否数组" prop="Port">
          <el-select
            style="width: 50%"
            v-model="variableForm.IsArray"
            placeholder="请选择数据类型"
            @change="changeVariableLength"
          >
            <el-option label="标量变量" :value="false"></el-option>
            <el-option label="一维数组" :value="true"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item v-show="variableForm.IsArray" label="数组长度" prop="IP">
          <el-input
            type="number"
            v-model.number="variableForm.ArrayLength"
            :min="1"
            :step="1"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button @click="variableVisable = false">取 消</el-button>
          <el-button
            type="primary"
            @click="
              () => {
                variableVisable = false;
                addPlcVariable(variableForm);
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <el-dialog destroy-on-close :visible.sync="importVisable" width="30%">
      <span slot="title" style="text-align: center"
        >{{
          importType == "all" && varType == 1
            ? "导入设备内部变量"
            : importType == "all" && varType == 2
            ? "导入项目变量"
            : "导入设备全部配置"
        }}
        <el-button
          type="text"
          style="margin-left: 450px"
          @click="DownLoadTemplate"
          >下载模板</el-button
        >
        <el-divider></el-divider>
        <el-upload
          class="upload-demo"
          :auto-upload="false"
          :file-list="fileList"
          ref="upload"
          drag
          action=""
          :on-change="addfile"
          :on-exceed="handleExceed"
          multiple
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
          <div class="import-icon" slot="tip">
            <i style="color: red" class="el-icon-warning-outline"></i>
            <span>{{
              `导入时,将对目标对象的${
                importType == "all" && varType == 1
                  ? "设备内部变量"
                  : importType == "all" && varType == 2
                  ? "项目变量"
                  : "设备全部配置"
              }进行全覆盖,请知悉!`
            }}</span>
          </div>
        </el-upload>
        <span slot="footer" class="dialog-footer" style="text-align: center">
          <el-divider></el-divider>
          <div>
            <el-button
              @click="
                () => {
                  importVisable = false;
                }
              "
              >取 消</el-button
            >
            <el-button
              :disabled="!importBtn"
              type="primary"
              @click="
                () => {
                  confirmImport(importType, varType);
                }
              "
              >确 定</el-button
            >
          </div>
        </span>
      </span>
    </el-dialog>
    <el-dialog
      @open="openDialog('globleFormRef')"
      destroy-on-close
      :visible.sync="globleVarVisable"
      width="30%"
    >
      <span slot="title" style="text-align: center"
        >{{ globleForm.Title }}
        <el-divider></el-divider>
      </span>
      <el-form
        ref="globleFormRef"
        :model="globleForm"
        :rules="globalRules"
        label-width="200px"
      >
        <el-form-item prop="alias" label="变量名">
          <el-input
            v-model="globleForm.alias"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item v-if="false" prop="name" label="变量地址">
          <el-input
            v-model="globleForm.name"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item prop="dataTypeId" label="变量类型" required>
          <el-select
            style="width: 50%"
            v-model="globleForm.dataTypeId"
            placeholder="请选择数据类型"
          >
            <el-option
              v-for="item in variableType"
              :key="item.name"
              :label="item.name"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <!-- <el-form-item label="变量地址" prop="IP">
          <el-input v-model="globleForm.name" style="width: 50%" autocomplete="off"></el-input>
        </el-form-item> -->
        <el-form-item prop="isArray" label="是否数组">
          <el-select
            style="width: 50%"
            v-model="globleForm.isArray"
            placeholder="请选择数据类型"
            @change="changeVariableLength"
          >
            <el-option label="标量变量" :value="false"></el-option>
            <el-option label="一维数组" :value="true"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          v-show="globleForm.isArray"
          prop="arrayLength"
          label="数组长度"
        >
          <el-input
            type="number"
            v-model.number="globleForm.arrayLength"
            style="width: 50%"
            :control="false"
            :value-on-clear="0"
            oninput="value=parseInt(value.replace(/[^\d]/g,''))"
            autocomplete="off"
            :min="1"
            :step="1"
          ></el-input>
        </el-form-item>

        <el-form-item prop="description" label="变量描述">
          <el-input
            v-model="globleForm.description"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item prop="isPersistence" label="数据保存" required>
          <el-select
            style="width: 50%"
            v-model="globleForm.isPersistence"
            placeholder="请选择数据保存类型"
            @change="changeVariableLength"
          >
            <el-option key="1" label="断电释放" :value="false"></el-option>
            <el-option key="2" label="断电保持" :value="true"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item prop="initValue" label="初始值">
          <el-input
            v-model="globleForm.initValue"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              () => {
                globleVarVisable = false;
              }
            "
            >取 消</el-button
          >
          <el-button
            type="primary"
            @click="
              () => {
                globalVarOperate(globleForm);
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <!-- 添加工序弹窗 -->
    <el-dialog
      destroy-on-close
      :visible.sync="addProcessVisable"
      width="30%"
      @open="openDialog('processForm')"
    >
      <span slot="title" style="text-align: center"
        >{{ processForm.Title }}
        <el-divider></el-divider>
      </span>
      <el-form :model="processForm" ref="processForm" label-width="200px">
        <el-form-item
          v-if="dialogVisable.name"
          :label="processForm.NameLabel"
          prop="Code"
          :rules="[{ required: true, message: '工序名称不可为空' }]"
        >
          <el-select v-model="processForm.Code" placeholder="请选择">
            <el-option
              v-for="(item, index) in processOption"
              :key="index"
              :label="item.name"
              :value="index"
            >
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              {
                addProcessVisable = false;
                closeForm('processForm');
              }
            "
            >取 消</el-button
          >
          <el-button
            type="primary"
            @click="
              () => {
                addProcess(processForm);
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <el-dialog
      @open="openDialog('monitorForm')"
      destroy-on-close
      :visible.sync="addMonitoredVisable"
      width="30%"
    >
      <span slot="title" style="text-align: center"
        >{{ monitoredForm.Title }}
        <el-divider></el-divider>
      </span>
      <el-form
        :model="monitoredForm"
        :rules="dialogRules"
        ref="monitorForm"
        label-width="200px"
      >
        <el-form-item label="扫描周期(ms):" prop="scanPeriod">
          <el-input
            type="number"
            style="width: 30%"
            v-model="monitoredForm.scanPeriod"
          ></el-input>
          <label> *100</label>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button @click="addMonitoredVisable = false">取 消</el-button>
          <el-button
            type="primary"
            @click="
              () => {
                addMonitored(monitoredForm);
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <el-dialog destroy-on-close :visible.sync="arrayUpdateVisable" width="30%">
      <span slot="title" style="text-align: center"
        >修改数组位变量
        <el-divider></el-divider>
      </span>
      <el-form :model="arrayUpdateForm" label-width="200px">
        <el-form-item label="变量名">
          <label> {{ arrayUpdateForm.alias }}</label>
        </el-form-item>
        <el-form-item label="变量描述">
          <el-input
            v-model="arrayUpdateForm.desc"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="初始值">
          <el-input
            v-model="arrayUpdateForm.initValue"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button @click="arrayUpdateVisable = false">取 消</el-button>
          <el-button
            type="primary"
            @click="
              () => {
                UpdateArrayDescript(arrayUpdateForm);
                arrayUpdateVisable = false;
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <!-- 批量加入监控 -->
    <el-dialog
      destroy-on-close
      :visible.sync="alladdMonitoredVisable"
      width="30%"
      @open="openDialog('allmonitoredForm')"
    >
      <span slot="title" style="text-align: center"
        >{{ monitoredForm.Title }}
        <el-divider></el-divider>
      </span>
      <el-form
        :model="monitoredForm"
        :rules="dialogRules"
        ref="allmonitoredForm"
        label-width="200px"
      >
        <el-form-item label="扫描周期(ms)" prop="scanPeriod">
          <el-input
            type="number"
            style="width: 30%"
            v-model="monitoredForm.scanPeriod"
          ></el-input>
          <label> *100</label>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button @click="alladdMonitoredVisable = false">取 消</el-button>
          <el-button
            type="primary"
            @click="
              () => {
                //AddMonitored(monitoredForm);
                AllAddMonitored(monitoredForm);
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <!-- 切换地址弹窗 -->
    <el-dialog
      destroy-on-close
      :visible.sync="changeAddressVisable"
      width="30%"
    >
      <span slot="title" style="text-align: center"
        >切换地址
        <el-divider></el-divider>
      </span>
      <div style="text-align: center; margin-top: 25px">
        <label>*地址切换为：</label>
        <el-radio-group v-model="changeAddressType">
          <el-radio
            v-for="(item, index) in networkConfig"
            :key="index"
            :label="String(item.id)"
            >{{ item.name }}</el-radio
          >
        </el-radio-group>
      </div>
      <div class="addressmsg">
        <i class="el-icon-warning-outline" style="color: red"></i>
        切换时,将对该节点下的所有设备>部件进行统一切换,请知悉
      </div>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button @click="changeAddressVisable = false">取 消</el-button>
          <el-button
            type="primary"
            @click="
              () => {
                changePartAddress();
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <!-- 修改项目弹窗 -->
    <el-dialog
      @open="openDialog('factoryForm')"
      :visible.sync="factoryVisable"
      width="30%"
      destroy-on-close
    >
      <span slot="title" style="text-align: center"
        >修改项目
        <el-divider></el-divider>
      </span>
      <el-form ref="factoryForm" :model="factoryForm" label-width="200px">
        <el-form-item
          label="项目名称"
          prop="name"
          :rules="[{ required: true, message: '项目名称不可为空' }]"
        >
          <el-input
            v-model="factoryForm.name"
            style="width: 50%"
            autocomplete="off"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              {
                factoryVisable = false;
              }
            "
            >取 消</el-button
          >
          <el-button type="primary" @click="updateFactoryName(factoryForm)"
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import * as XLSX from "xlsx";
import PlcVarTable from "./components/plcVarTable";
import PlcMsgCard from "./components/PlcMsgCard";
import $http from "../../utils/apiHelper";
import JSONBig from "json-bigint";
import { isNotNumber, isPositiveInteger } from "@/utils/numberHelper.js";
export default {
  name: "deviceView",
  components: {
    PlcVarTable,
    PlcMsgCard,
  },
  destroyed() {
    clearInterval(this.timer);
  },
  mounted() {},
  async created() {
    this.initNetwork();
    this.Refresh();
    this.selectDev("", 1, 1000);
    this.selectProcess("", 1, 1000);
    this.syncType = JSON.parse(
      this.$store.state.systemconfig.system.find(
        (x) => x.ConfigName == "IsSync"
      ).Config
    );
  },
  data() {
    const validatePeriod = (rule, value, callback) => {
      if (value === undefined || value === "") {
        callback(new Error("扫描周期不能为空"));
      }
      if (isNotNumber(value)) {
        callback(new Error("扫描周期必须为数字"));
      }
      if (!isPositiveInteger(value)) {
        callback(new Error("扫描周期必须为正整数"));
      }
      //  if (!isPositiveInteger(value / 100)) {
      //   callback(new Error("扫描周期必须为100的整数倍"));
      // }
      // if (value > 100) {
      //   callback(new Error("扫描周期必须为小于等于100"));
      // }
      callback();
    };
    const validateEquipindex = (rule, value, callback) => {
      if (!this.dialogVisable.level) {
        callback();
      }
      //console.log("valute", value);
      if (value === "") {
        callback(new Error("设备分类不能为空"));
      }
      callback();
    };
    const ipRegex = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/;
    const portRegex = /^[1-9]\d{0,3}$/;
    const ipRegexN = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/;
    const portRegexN = /^[1-9]\d{0,3}$/;
    const validateIP = (rule, value, callback) => {
      if (this.networkConfig[0].IP === "") {
        callback(new Error("IP不能为空"));
      }
      if (!ipRegex.test(this.networkConfig[0].IP)) {
        callback(new Error("IP地址格式不正确"));
      }
      callback();
    };
    const validateIP1 = (rule, value, callback) => {
      console.log("validateAnyIP", rule, value, callback);
      if (
        this.networkConfig[1].IP &&
        !ipRegexN.test(this.networkConfig[1].IP)
      ) {
        callback(new Error("IP地址格式不正确"));
      }
      callback();
    };
    const validatePort = (rule, value, callback) => {
      if (this.networkConfig[0].Port == undefined) {
        callback(new Error("端口号不能为空"));
      }
      // if ((this.networkConfig[0].Port).trim() === ""){
      //   callback(new Error("端口号不能为空"));
      // }
      if (!portRegex.test(this.networkConfig[0].Port)) {
        callback(new Error("端口号格式不正确"));
      }
      callback();
    };
    const validatePort1 = (rule, value, callback) => {
      if (
        this.networkConfig[1].Port &&
        !portRegexN.test(this.networkConfig[1].Port)
      ) {
        callback(new Error("端口号格式不正确"));
      }
      callback();
    };
    const validateIP2 = (rule, value, callback) => {
      console.log("validateAnyIP", rule, value, callback);
      if (
        this.networkConfig[2].IP &&
        !ipRegexN.test(this.networkConfig[2].IP)
      ) {
        callback(new Error("IP地址格式不正确"));
      }
      callback();
    };
    const validatePort2 = (rule, value, callback) => {
      if (
        this.networkConfig[2].Port &&
        !portRegexN.test(this.networkConfig[2].Port)
      ) {
        callback(new Error("端口号格式不正确"));
      }
      callback();
    };
    const validateIP3 = (rule, value, callback) => {
      console.log("validateAnyIP", rule, value, callback);
      if (
        this.networkConfig[3].IP &&
        !ipRegexN.test(this.networkConfig[3].IP)
      ) {
        callback(new Error("IP地址格式不正确"));
      }
      callback();
    };
    const validatePort3 = (rule, value, callback) => {
      if (
        this.networkConfig[3].Port &&
        !portRegexN.test(this.networkConfig[3].Port)
      ) {
        callback(new Error("端口号格式不正确"));
      }
      callback();
    };

    const validateNetworkConfig = (rule, value, callback) => {
      callback();
    };
    const validateArray = (rule, value, callback) => {
      if (!this.globleForm.isArray) {
        callback();
      }
      //console.log("valute", value);
      if (value === "") {
        callback(new Error("数组长度不能为空"));
      } else if (isNotNumber(value)) {
        callback(new Error("数组长度必须为数字"));
      } else if (!isPositiveInteger(value)) {
        callback(new Error("数组长度必须为正整数"));
      }
      callback();
    };
    return {
      factoryCodeVisable: true,
      factoryForm: { name: "" },
      syncLoading: false,
      syncType: false,
      sonPageNum: 0,
      connectionId: "",
      timer: "",
      devIconData: "",
      checkedTable: false,
      expandedKey: "",
      defaultCheckedKeys: "",
      checkedKey: "",
      programName: "",
      processName: "",
      lineName: "",
      equName: "",
      equCode: "",
      equCategory: "",
      arrayUpdateVisable: false,
      arrayUpdateForm: {},
      monitoredForm: { scanPeriod: 1 },
      addMonitoredVisable: false,
      globalRules: {
        alias: [
          { required: true, message: "变量名不可为空", trigger: "blur" },

          {
            validator: (rule, value, callback) => {
              const reg = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
              if (reg.test(value)) {
                callback();
              } else {
                callback(new Error("变量名不符合命名规范"));
              }
            },
            trigger: "change",
          },
        ],
        name: [
          { required: true, message: "变量地址不可为空", trigger: "blur" },
        ],
        // description: [
        //   { required: true, message: "变量描述不可为空", trigger: "blur" },
        // ],
        // initValue: [
        //   { required: true, message: "初始值不可为空", trigger: "blur" },
        // ],
        isArray: [
          { required: true, message: "数组长度不可为空", trigger: "blur" },
        ],
        arrayLength: [
          { required: true, validator: validateArray, trigger: "change" },
        ],
      },
      alias: "",
      pageNum: 1,
      pageSize: 20,
      total: 1,
      rightNode: {},
      currentObj: {},
      deviceOption: [],
      processOption: [],
      addProcessVisable: false,
      processForm: {},
      importType: "plc,",
      importContent: "",
      varType: 2,
      globleForm: {
        Title: "",
        Url: "",
        id: 0,
        isArray: true,
        arrayLength: 0,
        currPage: 1,
        pageSize: 10,
        eqId: 0,
        alias: "",
        name: "",
        isMonitored: false,
        dataTypeId: 0,
        valueType: 2,
      },
      globleVarVisable: false,
      nowNode: "",
      importBtn: false,
      fileList: [],
      selectVariableModel: {
        PlcId: 0,
        Alias: "",
        Name: "",
        IsMonitored: 0,
        Url: "",
        Message: "",
      },
      // 变量类型选项
      variableOption: [
        { name: "全部", value: 0 },
        { name: "Boolean", value: 1 },
        { name: "SByte", value: 2 },
        { name: "Byte", value: 3 },
        { name: "Int16", value: 4 },
        { name: "UInt16", value: 5 },
        { name: "Int32", value: 6 },
        { name: "UInt32", value: 7 },
        { name: "Int64", value: 8 },
        { name: "UInt64", value: 9 },
        { name: "Float", value: 10 },
        { name: "Double", value: 11 },
        { name: "String", value: 12 },
      ],
      variableType: [
        { name: "Boolean", value: 1 },
        { name: "SByte", value: 2 },
        { name: "Byte", value: 3 },
        { name: "Int16", value: 4 },
        { name: "UInt16", value: 5 },
        { name: "Int32", value: 6 },
        { name: "UInt32", value: 7 },
        { name: "Int64", value: 8 },
        { name: "UInt64", value: 9 },
        { name: "Float", value: 10 },
        { name: "Double", value: 11 },
        { name: "String", value: 12 },
      ],
      variableForm: {
        Title: "",
        Alias: "",
        Name: "",
        Id: 0,
        PlcId: 0,
        IsArray: false,
        IsMonitored: false,
        DataTypeId: 1,
        ArrayLength: 0,
      },
      variableVisable: false,
      plcSettingVisable: false,
      importVisable: false,

      dialogVisable: { name: false, code: false, level: false },
      lineForm: {
        NameLabel: "",
        CodeLabel: "",
        Name: "",
        Id: 0,
        Code: "",
        ParentId: 0,
        Title: "",
        Message: "",
        Type: "",
        Url: "",
        Equipindex: "",
      },
      rules: {
        Name: [
          { required: true, message: "设备名称不能为空", trigger: "blur" },
        ],
        Code: [
          { required: true, message: "设备编码不能为空", trigger: "blur" },
        ],
        Equipindex: [
          { required: true, validator: validateEquipindex, trigger: "blur" },
        ],
      },
      plcForm: {
        Name: "",
        ID: 0,
        CommunicationType: 6,
        ParentId: 0,
        IP: [],
        TimeOut: "",
        Port: [],
        UserName: "",
        Password: "",
        Title: "",
        Message: "",
        Type: 0,
        Url: "",
        MaxDisconnection: -1,
      },

      plcRules: {
        Name: [
          { required: true, message: "部件名称不能为空", trigger: "blur" },
        ],
        //写成定值是无奈之举，根本解决方法是修改数据库结构，使表单校验中的value可以获取
        networkConfig0: [{ required: true, validator: validateNetworkConfig }],
        IP0: [{ validator: validateIP, trigger: "change", required: true }],
        Port0: [{ validator: validatePort, trigger: "change", required: true }],
        IP1: [{ validator: validateIP1, trigger: "change" }],
        Port1: [{ validator: validatePort1, trigger: "change" }],
        IP2: [{ validator: validateIP2, trigger: "change" }],
        Port2: [{ validator: validatePort2, trigger: "change" }],
        IP3: [{ validator: validateIP3, trigger: "change" }],
        Port3: [{ validator: validatePort3, trigger: "change" }],
        CommunicationType: [
          { required: true, message: "通讯类型不能为空", trigger: "blur" },
        ],
        // IP: [{ required: true, message: "IP地址不能为空", trigger: "blur" }],
        // Port: [{ required: true, message: "端口号不能为空", trigger: "blur" }],
        TimeOut: [
          { required: true, message: "超时时间不能为空", trigger: "blur" },
          {
            pattern: /^(?:[1-9]\d*|-1)$/,
            message: "只可以输入正整数和-1",
            trigger: "blur",
          },
        ],
        MaxDisconnection: [
          { required: true, message: "掉线判断阈值不可为空", trigger: "blur" },
          {
            pattern: /^(?:[1-9]\d*|-1)$/,
            message: "只可以输入正整数和-1",
            trigger: "blur",
          },
        ],
      },
      addLineVisable: false,
      seletNode: "",
      props: {
        label: "DisplayName",
        children: "Children",
      },
      treeData: [],
      dataTypeId: 0,
      isPowerSave: 0,
      isMonitor: 0,
      globalType: 2, // 1:项目，2：设备
      datasource: [],
      form: {},
      options: [
        {
          value: 1,
          label: "OmronConnCip",
        },
        {
          value: 2,
          label: "BckoffAds6",
        },
        {
          value: 3,
          label: "TcpSocket",
        },
        {
          value: 4,
          label: "BckoffAds",
        },
        {
          value: 5,
          label: "OmronCip",
        },
        {
          value: 6,
          label: "OpcUA",
        },
      ],
      isAdd: false,
      model: 0,
      formLabelWidth: "120px",
      filterText: "",
      plcmsg: {
        Name: "",
        CommunicationType: "",
        IP: "",
        Port: "",
        TimeOut: "",
      },
      tableData: [],
      globalVariable: {
        id: 0,
        isArray: true,
        arrayLength: 0,
        currPage: 1,
        pageSize: 10,
        eqId: 0,
        alias: "",
        name: "",
        isMonitored: false,
        dataTypeId: 0,
        valueType: 2,
      },
      globalTable: [],
      equTable: [],
      sonTotal: 1,
      expandLoading: false,
      fahtherCheckedAll: [],
      fahtherCheckedEqu: [],
      sonCheckedAll: [],
      sonCheckedEqu: [],
      alladdMonitoredVisable: false,
      sonCheckedAllSelected: [],
      sonCheckedEquSelected: [],
      changeAddressVisable: false,
      changeAddressType: 0,
      networkConfig: [],
      ipConfig: "",
      portConfig: "",
      searchConditionLast: {
        pageSize: 0,
        currentPage: 0,
        eqId: 0, //全局变量不需要设备id
        alias: "",
        isPersistence: 0,
        dataTypeId: 0,
        isMonitored: false,
        isEqGol: 0,
      },
      searchSonConditionLast: {
        alias: "",
        name: "",
        currPage: 0,
        id: 0,
        monitoredState: false,
        dataType: 0,
        persistenceState: 0,
      },
      monitorForm: {
        scanPeriod: 1,
      },
      allmonitoredForm: {
        scanPeriod: 1,
      },
      dialogRules: {
        scanPeriod: [
          { validator: validatePeriod, trigger: "change", required: true },
        ],
      },
      globleFormRef: {
        alias: "",
        name: "",
        dataTypeId: "",
        isArray: "",
        arrayLength: "",
        description: "",
        isPersistence: "",
        initValue: "",
      },

      factoryVisable: false,
      expandedRowKeys: [],
    };
  },
  computed: {
    displayScanPeriod() {
      return (scanPeriod) => {
        if (scanPeriod === 0) {
          return ""; // 当 ScanPeriod 为 0 时返回空字符串
        } else {
          return scanPeriod * 100; // 其他情况返回实际的 ScanPeriod 值
        }
      };
    },
    isModbus() {
      if (this.plcmsg.CommunicationType == 7) {
        return true;
      }
      return false;
    },
    cardVisable() {
      if (this.nowNode) {
        switch (this.nowNode.data.SortIndex) {
          case 0:
            return {
              all: true,
              equ: false,
              plc: false,
              line: false,
              process: false,
              isLineOrProcess: false,
            };
          case 1:
            return {
              all: false,
              equ: false,
              plc: false,
              line: true,
              process: false,
              isLineOrProcess: true,
            };
          case 2:
            return {
              all: false,
              equ: false,
              plc: false,
              line: false,
              process: true,
              isLineOrProcess: true,
            };
          case 3:
            return {
              all: false,
              equ: true,
              plc: false,
              line: false,
              process: false,
              isLineOrProcess: false,
            };
          case 4:
            return {
              all: false,
              equ: false,
              plc: true,
              line: false,
              process: false,
              isLineOrProcess: false,
            };
          default:
            return {
              all: true,
              equ: false,
              plc: false,
              line: false,
              process: false,
              isLineOrProcess: false,
            };
        }
      } else {
        return {
          all: true,
          equ: false,
          plc: false,
          line: false,
          process: false,
          isLineOrProcess: false,
        };
      }
    },
    importBtnVisable() {
      if (this.nowNode) {
        if (
          this.nowNode.data.SortIndex == 3 ||
          this.nowNode.data.SortIndex == 1 ||
          this.nowNode.data.SortIndex == 4
        ) {
          return true;
        } else {
          return false;
        }
      } else {
        return false;
      }
    },
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
      //console.log("节点筛选", this.$refs.tree);
    },
    // expandedKey(newVal, oldVal) {
    //   if (newVal) {
    //     this.$nextTick(() => {
    //       document
    //         .querySelector(".el-tree-node__children .el-tree-node__content")
    //         .click();
    //     });
    //   }
    // },
  },

  methods: {
    updateFactoryName(form) {
      this.$refs.factoryForm.validate((valid) => {
        if (!valid) {
          this.$message.error("项目名称不可为空");
        } else {
          let param = { Name: form.name, Id: form.id, Code: "", ParentId: 0 };
          $http.post("/EqManage/UpdateFactoryName", param).then((res) => {
            if (res.Data) {
              this.$message.success("项目名称修改成功");
              this.factoryVisable = false;
              this.Refresh();
            } else {
              this.$message.error(res.Message);
            }
          });
        }
      });
    },

    /**
     * 在打开弹窗时清除掉表单的校验规则，不然在打开弹窗时默认会校验一次
     * @param {表单ref名} formName
     */
    openDialog(formName) {
      this.$nextTick(() => {
        this.$refs[formName].clearValidate();
      });
    },
    closeForm(name) {
      this.$refs[name].clearValidate();
    },
    closeLineForm() {
      this.$refs.lineForm.clearValidate();
    },
    table_index(index) {
      return (this.pageNum - 1) * this.pageSize + index + 1;
    },
    syncFunc() {
      const h = this.$createElement;
      this.$confirm(
        "此操作将永久删除该文件, 是否继续?",
        "确定启用设备同步模式?",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
          center: true,
          message: h("p", null, [
            h(
              "p",
              { style: "color: red" },
              "*注意:同步结构后,设备台账从MES系统获取,不在独立维护"
            ),
            h("p", { style: "color: red" }, null),
          ]),
        }
      ).then(() => {
        this.syncLoading = true;
        $http.get("/EpmSync/SyncMesStruct", { timeout: 50000 }).then((res) => {
          if (res.Data == true) {
            this.syncLoading = false;
            this.$message({
              message: "同步成功",
              type: "success",
            });
            this.Refresh();
            this.selectDev("", 1, 1000);
            this.selectProcess("", 1, 1000);
            this.syncType = true;
            //屏蔽字典菜单
            this.$store.commit(
              "permission/SET_ROUTES",
              this.$store.state.permission.routes.filter(
                (m) => m.meta.isSync != true
              )
            );
            // this.$store.state.permission.routes.filter
          } else {
            this.$message.error("同步失败");
          }
        });
      });
    },
    updateVarFunc(scope) {
      var param = scope.row;
      this.globleForm = {
        Url: "",
        Title: "",
        id: param.ID,
        isArray: param.IsArray,
        arrayLength: param.ArrayLength,
        eqId: this.varType == 1 ? this.nowNode.data.StructGuid : 0,
        alias: param.Alias,
        name: param.DataName,
        isMonitored: param.isMonitored,
        dataTypeId: param.DataType,
        valueType: param.ValueType,
        description: param.Description,
        isPersistence: param.IsPersistence,
        initValue: param.InitValue,
      };
      this.globleForm.Url = "/EqManage/UpdateEqGlobalVarInfo";
      this.globleForm.Title =
        this.varType == 1 ? "修改设备内部变量" : "修改项目变量";
      this.globleVarVisable = true;
      if (this.$refs.globleFormRef) {
        this.$refs.globleFormRef.resetFields();
      }
    },
    addVarFunc() {
      //debugger;
      this.globleForm = {
        Url: "",
        Title: "",
        id: 0,
        isArray: false,
        arrayLength: 0,
        eqId: this.varType == 1 ? this.nowNode.data.StructGuid : 0,
        alias: "",
        name: "",
        isMonitored: false,
        dataTypeId: 1,
        valueType: this.varType,
        description: "",
        isPersistence: false,
        initValue: "",
      };
      this.globleForm.Url = "/EqManage/InsertEqGlobalVariable";
      this.globleForm.Title =
        this.varType == 1 ? "新建设备内部变量" : "新建项目变量";
      this.globleVarVisable = true;

      if (this.$refs.globleFormRef) {
        this.$refs.globleFormRef.resetFields();
      }
    },
    changePartAddress() {
      if (this.changeAddressType && this.seletNode) {
        let param = {
          Id: this.changeAddressType,
          SortIndex: this.seletNode.SortIndex,
          NodeId: this.seletNode.StructGuid,
        };
        $http.post("/EqManage/ChangePartConnect", param).then((res) => {
          if (res.Data) {
            if (res.Data.length > 0) {
              let title = this.networkConfig.find(
                (x) => String(x.id) == param.Id
              ).name;
              //console.log('resdata',res.Data);
              //console.log('rightnode',this.rightNode );
              //console.log('this.treeData',this.treeData );
              let msg = res.Data.map((item) => {
                const parentName = this.getParentName(item.ID, this.treeData);
                return parentName + "->" + item.Name;
              }).join(";");
              this.$confirm(
                `请补充连接地址信息，${msg}`,
                `${title}不存在，切换失败`,
                {
                  confirmButtonText: "知道了",
                  showCancelButton: false,
                  type: "error",
                  center: true,
                }
              )
                .then(() => {})
                .catch(() => {
                  this.$message({
                    type: "info",
                    message: "已取消删除",
                  });
                });
              // this.$confirm(
              //   `请补充连接地址信息，${msg}`,
              //   `${title}不存在，切换失败`,
              //   {
              //     confirmButtonText: "确定",
              //     type: "error",
              //     center: false,
              //   }
              // );

              //this.$message.success("切换成功");
            } else {
              this.$message.success("切换成功");
              this.refreshRight();
            }
            this.changeAddressType = "";
            this.changeAddressVisable = false;
          } else {
            this.$message.error(`切换网络地址失败,${res.Message}`);
          }
        });
      } else {
        this.$message.error(`需要选中一个网络地址类型`);
      }
    },
    change() {
      this.$forceUpdate;
    },
    initNetwork() {
      $http.get("/EQDictionary/GetNetworkInfo").then((res) => {
        if (res.Data) {
          this.networkConfig = [];
          if (res.Data && res.Data.length > 0) {
            res.Data.forEach((d) => {
              this.networkConfig.push(Object.assign(d, { IP: "", Port: "" }));
            });
          }
          // this.networkConfig = res.Data;
          // this.networkConfig.forEach((m) => {
          //   (m.ip = ""), (m.port = "");
          // });
        }
      });
    },
    DeleteAllVar() {
      this.$confirm(
        `此操作批量删除${
          this.globalType == 2 ? "项目" : "设备内部"
        }变量, 是否继续?`,
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      )
        .then(() => {
          let value =
            this.globalType == 2
              ? this.fahtherCheckedAll
              : this.fahtherCheckedEqu;
          $http
            .post(
              "/EqManage/BatchEqArrayDelete",
              JSON.parse(JSON.stringify(value))
            )
            .then((res) => {
              if (res.Data) {
                this.$message.success(
                  `批量删除${
                    this.globalType == 2 ? "项目" : "设备内部"
                  }变量成功`
                );
                this.selectGlobleVar();
              } else {
                this.$message({
                  type: "error",
                  message:
                    `批量删除${
                      this.globalType == 2 ? "项目" : "设备内部"
                    }变量失败` + res.Message,
                });
              }
              //刷新变量栏目
            });
        })
        .catch((err) => {
          this.$message.error(
            `批量删除${this.globalType == 2 ? "项目" : "设备内部"}变量失败` +
              err
          );
        });
    },
    /**
     * 过滤选中的项目子节点
     * @param {选中的父节点} father
     * @param {选中的子节点} son
     */
    filterSon(father, son) {
      //去掉在父类下的子元素
      let sonRes = son.filter(
        (sonItem) =>
          !father.some((fatherItem) =>
            sonItem.ParentId.isEqualTo(fatherItem.ID)
          )
      );
      return { father, sonRes };
    },

    DownLoadTemplate() {
      $http
        .get(`/EqManage/DownLoadEqVarDataTemplate`, {
          responseType: "blob",
        })
        .then((res) => {
          if (res) {
            const url = window.URL.createObjectURL(
              new Blob([res], { type: "application/vnd.ms-excel" })
            );
            const link = document.createElement("a");
            link.href = url;
            link.setAttribute("download", `deviceTemplate.xlsx`);
            document.body.appendChild(link);
            link.click();
          } else {
            this.$message({
              type: "error",
              message: "导出部件变量失败",
            });
          }
        })
        .catch((error) => {
          //debugger;
          this.$message({
            type: "error",
            message: `${error.response.data.Message}`,
          });
        });
    },
    /**
     * 批量加入监控
     * @param {*} form
     */
    AllAddMonitored(form) {
      //debugger
      //判断整理加入监控的数组和非数组，去重
      if (form) {
        if (form.isMonitored) {
          this.$refs.allmonitoredForm.validate((valid) => {
            if (!valid) {
              return;
            } else {
              // this.monitoredForm.scanPeriod =
              //   this.monitoredForm.scanPeriod / 100;
              //debugger
              if (this.globalType == 2) {
                let value = form.isMonitored;

                //去掉已加入监控的非数组
                // let father = this.fahtherCheckedAll.filter(
                //   (m) => !(m.IsArray == true && m.IsMonitored == value)
                // );
                //去掉已加入监控的子级元素
                // let son = this.sonCheckedAllSelected.filter(
                //   (m) => !(m.IsArray == true && m.IsMonitored == value)
                // );
                // let fatherRes = father.filter(
                //   (itemA) =>
                //     !son.some(
                //       (itemB) =>
                //         JSON.stringify(itemA.ID) ==
                //         JSON.stringify(itemB.ParentId)
                //     )
                // );
                // //console.log(form);
                // //console.log("数组变量", this.fahtherChecked);
                // //console.log("非数组", this.sonChecked);
                // //console.log("过滤父级元素", father);
                // //console.log("过滤子级元素", son);
                // //console.log("过滤父级包含子级", fatherRes);
                const fatherAndSon = this.filterSon(
                  this.fahtherCheckedAll,
                  this.sonCheckedAllSelected
                );
                $http
                  .post(
                    "/EqManage/BatchEqMonitor",

                    {
                      ParentList: fatherAndSon.father,
                      ChildList: fatherAndSon.sonRes,
                      IsMonitorChecked: value,
                      ScanPeriod: form.scanPeriod,
                    }
                  )
                  .then((res) => {
                    if (res.Data) {
                      this.fahtherCheckedAll = [];
                      this.sonCheckedAll = [];
                      this.sonCheckedAllSelected = [];
                      this.$message.success("批量加入监控成功");
                      this.alladdMonitoredVisable = false;
                      this.expandHandle();
                      this.selectGlobleVar();
                      this.$refs.multipleTable.clearSelection();
                    } else {
                      this.$refs.multipleTable.clearSelection();
                      this.$confirm(`${res.Message}`, "变量加入监控操作失败", {
                        confirmButtonText: "确定",
                        showCancelButton: false,
                        type: "error",
                      });
                    }
                    //刷新变量栏目
                  });
              } else if (this.globalType == 1) {
                // if (this.fahtherCheckedEqu.length == 0 && this.sonCheckedEquSelected.length === 0 ) {
                //   this.$message.error("请至少选中一个节点");
                //   return;
                // }
                let value = form.isMonitored;
                //去掉已加入监控的非数组
                // let father = this.fahtherCheckedEqu.filter(
                //   (m) => !(m.IsArray == true && m.IsMonitored == value)
                // );
                //去掉已加入监控的子级元素
                // let son = this.sonCheckedEquSelected.filter(
                //   (m) => !(m.IsArray == true && m.IsMonitored == value)
                // );

                // let fatherRes = father.filter(
                //   (itemA) =>
                //     !son.some(
                //       (itemB) =>
                //         JSON.stringify(itemA.ID) ==
                //         JSON.stringify(itemB.ParentId)
                //     )
                // );
                // //console.log(form);
                // //console.log("数组变量", this.fahtherChecked);
                // //console.log("非数组", this.sonChecked);
                // //console.log("过滤父级元素", father);
                // //console.log("过滤子级元素", son);
                // //console.log("过滤父级包含子级", fatherRes);
                const fatherAndSon = this.filterSon(
                  this.fahtherCheckedEqu,
                  this.sonCheckedEquSelected
                );
                $http
                  .post(
                    "/EqManage/BatchEqMonitor",

                    {
                      ParentList: fatherAndSon.father,
                      ChildList: fatherAndSon.sonRes,
                      IsMonitorChecked: value,
                      ScanPeriod: form.scanPeriod,
                    }
                  )
                  .then((res) => {
                    if (res.Data) {
                      this.fahtherCheckedEqu = [];
                      this.sonCheckedEqu = [];
                      this.sonCheckedEquSelected = [];
                      this.$refs.multipleTable.clearSelection();
                      this.$message.success("批量加入监控成功");
                      this.alladdMonitoredVisable = false;
                      this.expandHandle();
                      this.selectGlobleVar();
                    } else {
                      this.$refs.multipleTable.clearSelection();
                      this.$message({
                        type: "error",
                        message: "批量加入失败" + res.Message,
                      });
                    }
                    //刷新变量栏目
                  });
              }
            }
          });
        } else {
          //debugger
          if (this.globalType == 2) {
            if (
              this.fahtherCheckedAll.length == 0 &&
              this.sonCheckedAllSelected.length === 0
            ) {
              this.$message.error("请至少选中一个节点");
              return;
            }
            let value = form.isMonitored;
            //去掉已加入监控的非数组
            // let father = this.fahtherCheckedAll.filter(
            //   (m) => !(m.IsArray == true && m.IsMonitored == value)
            // );
            //去掉已加入监控的子级元素
            // let son = this.sonCheckedAllSelected.filter(
            //   (m) => !(m.IsArray == true && m.IsMonitored == value)
            // );
            // let fatherRes = father.filter(
            //   (itemA) =>
            //     !son.some(
            //       (itemB) =>
            //         JSON.stringify(itemA.ID) == JSON.stringify(itemB.ParentId)
            //     )
            // );
            // //console.log(form);
            // //console.log("数组变量", this.fahtherChecked);
            // //console.log("非数组", this.sonChecked);
            // //console.log("过滤父级元素", father);
            // //console.log("过滤子级元素", son);
            // //console.log("过滤父级包含子级", fatherRes);
            const fatherAndSon = this.filterSon(
              this.fahtherCheckedAll,
              this.sonCheckedAllSelected
            );
            $http
              .post(
                "/EqManage/BatchEqMonitor",

                {
                  ParentList: fatherAndSon.father,
                  ChildList: fatherAndSon.sonRes,
                  IsMonitorChecked: value,
                  ScanPeriod: 0,
                }
              )
              .then((res) => {
                //debugger
                if (res.Data) {
                  this.fahtherCheckedAll = [];
                  this.sonCheckedAll = [];
                  this.sonCheckedAllSelected = [];
                  this.$refs.multipleTable.clearSelection();
                  this.$message.success("批量取消监控成功");
                  this.alladdMonitoredVisable = false;
                  this.expandHandle();
                  this.selectGlobleVar();
                } else {
                  this.$refs.multipleTable.clearSelection();
                  this.$confirm(`${res.Message}`, "变量取消监控操作失败", {
                    confirmButtonText: "确定",
                    showCancelButton: false,
                    type: "error",
                  });
                }
                //刷新变量栏目
              });
          } else if (this.globalType == 1) {
            if (
              this.fahtherCheckedEqu.length == 0 &&
              this.sonCheckedEquSelected.length === 0
            ) {
              this.$message.error("请至少选中一个节点");
              return;
            }
            let value = form.isMonitored;
            //去掉已加入监控的非数组
            // let father = this.fahtherCheckedEqu.filter(
            //   (m) => !(m.IsArray == true && m.IsMonitored == value)
            // );
            //去掉已加入监控的子级元素
            // let son = this.sonCheckedEquSelected.filter(
            //   (m) => !(m.IsArray == true && m.IsMonitored == value)
            // );

            // let fatherRes = father.filter(
            //   (itemA) =>
            //     !son.some(
            //       (itemB) =>
            //         JSON.stringify(itemA.ID) == JSON.stringify(itemB.ParentId)
            //     )
            // );
            // //console.log(form);
            // //console.log("数组变量", this.fahtherChecked);
            // //console.log("非数组", this.sonChecked);
            // //console.log("过滤父级元素", father);
            // //console.log("过滤子级元素", son);
            // //console.log("过滤父级包含子级", fatherRes);
            const fatherAndSon = this.filterSon(
              this.fahtherCheckedEqu,
              this.sonCheckedEquSelected
            );
            $http
              .post(
                "/EqManage/BatchEqMonitor",

                {
                  ParentList: fatherAndSon.father,
                  ChildList: fatherAndSon.sonRes,
                  IsMonitorChecked: value,
                  ScanPeriod: 0,
                }
              )
              .then((res) => {
                if (res.Data) {
                  this.fahtherCheckedEqu = [];
                  this.sonCheckedEqu = [];
                  this.sonCheckedEquSelected = [];
                  this.$refs.multipleTable.clearSelection();
                  this.$message.success("批量取消监控成功");
                  this.alladdMonitoredVisable = false;
                  this.expandHandle();
                  this.selectGlobleVar();
                } else {
                  this.$refs.multipleTable.clearSelection();
                  this.$message({
                    type: "error",
                    message: "批量加入失败" + res.Message,
                  });
                }
                //刷新变量栏目
              });
          }
        }
      }
    },
    testConsole(param) {
      //console.log("测试打印参数", param);
    },
    getRowExpandData(id, type, allarray, equarray) {
      let exArray = type == 2 ? allarray : equarray;
      let param = [];
      ////console.log("数据到位,打印this", this);
      // //console.log("id", id);
      // //console.log("type", type);
      // //console.log("allarray", allarray);
      // //console.log("equarray", equarray);
      let res = exArray.find((m) => m.id.isEqualTo(id));
      ////console.log("res", res);
      if (res) {
        param = res.data;
        // res.data.forEach((m) => {
        //   this.$refs[`sontable${id}`].toggleRowSelection(m, true);
        // });
      }
      ////console.log("innertable", param);
      //选中子项所有项
      return param;
    },

    sonHandleSelectionChange(event) {
      ////console.log("操作子级选中", event);
      event.forEach((m) => {
        if (this.globalType == 2) {
          this.mergeDuplicates(this.sonCheckedAllSelected, m);
          ////console.log("打印全局子级", this.sonCheckedAllSelected);
        } else if (this.globalType == 1) {
          this.mergeDuplicates(this.sonCheckedEquSelected, m);
          ////console.log("打印设备子级", this.sonCheckedEquSelected);
        }
      });
    },
    // mergeItems(existingItem, newItem) {
    //   // 这里假设将两个对象的属性进行合并
    //   return {
    //     ...existingItem,
    //     ...newItem,
    //   };
    // },
    mergeDuplicates(array, item) {
      // 检查数组中是否已存在相同的项
      const index = array.findIndex((element) => {
        // 这里假设数组中的元素是对象，且对象具有唯一的标识属性，比如'id'
        return element.Alias === item.Alias;
      });

      if (index !== -1) {
        // 如果存在相同的项，进行合并操作
        array[index] = this.mergeItems(array[index], item);
      } else {
        // 如果不存在相同的项，直接将新项添加到数组中
        array.push(item);
      }
    },
    /**
     * 只允许展开一行
     * @param {*} row
     */
    expandOnlyRows(row) {
      //console.log("this.expandedRowKeys", this.expandedRowKeys);
      if (this.expandedRowKeys.length > 0) {
        const index = this.expandedRowKeys.indexOf(row.Alias);
        //console.log("index", index);
        if (index != -1) {
          this.expandedRowKeys.splice(index, 1);
        } else {
          this.expandedRowKeys.splice(0, this.expandedRowKeys.length);
          this.expandedRowKeys.push(row.Alias);
        }
      } else {
        this.expandedRowKeys.push(row.Alias);
      }
    },
    expandValue(event, obj) {
      //console.log("event", event);
      //console.log("obj", obj);
      if (event.IsArray) {
        this.expandOnlyRows(event);
        this.expandEvent = event;
        this.expandObj = obj;
        this.expandHandle();
      }
    },
    expandHandle() {
      this.expandLoading = true;
      console.log("展开数组测试", this.expandEvent, this.expandObj);
      ////console.log("初始化加载确定this", this);
      let param = {
        alias: this.alias,
        name: "",
        currPage: this.sonPageNum,
        id: this.expandEvent ? this.expandEvent.ID : 0,
        monitoredState: this.isMonitor,
        dataType: this.dataType,
        persistenceState: this.isPowerSave,
      };
      //console.log("param", param);
      let isDifferent = false;
      for (let key in param) {
        if (
          key !== "currPage" &&
          JSON.stringify(param[key]) !==
            JSON.stringify(this.searchSonConditionLast[key])
        ) {
          isDifferent = true;
          break;
        }
      }

      if (isDifferent) {
        this.sonPageNum = 1;
        param.currPage = 1;
      }

      this.searchSonConditionLast = param;

      if (this.expandObj && this.expandObj.length > 0) {
        //console.log("展开事件触发");
        $http
          .post(`/EqManage/EqArrayDataExpand`, param)
          .then((res) => {
            if (res.Data != null) {
              //将数据加入到需要的集合中
              this.sonTotal = res.Data.totalCount;
              //console.log("sonCheckedAll", this.sonCheckedAll);
              //console.log("this.globalType", this.globalType);
              //console.log("this.expandEvent.ID", this.expandEvent.ID);
              //console.log("this.sonCheckedEqu", this.sonCheckedEqu);
              if (this.globalType == 2) {
                this.sonCheckedAll.splice(
                  this.sonCheckedAll.findIndex(
                    (m) => m.id == this.expandEvent.ID
                  ),
                  1,
                  {
                    id: this.expandEvent.ID,
                    data: res.Data.pageData,
                  }
                );
              } else if (this.globalType == 1) {
                this.sonCheckedEqu.splice(
                  this.sonCheckedEqu.findIndex(
                    (m) => m.id == this.expandEvent.ID
                  ),
                  1,
                  {
                    id: this.expandEvent.ID,
                    data: res.Data.pageData,
                  }
                );
              }

              this.expandLoading = false;
            } else {
              this.expandLoading = false;
            }
          })
          .catch((err) => {
            //console.log(err);
            this.expandLoading = false;
          });
      }
    },
    // 表格选中事件
    checkedBoxHandler(event, obj) {
      if (this.globalType == 2) {
        this.fahtherCheckedAll = event;
      } else if (this.globalType == 1) {
        this.fahtherCheckedEqu = event;
      }
    },
    fatherSelectAllHandler(event) {
      if (this.globalType == 2) {
        //console.log("111", event);
        this.fahtherCheckedAll = event;
        //全选时要选中所有级别,或取消所有级别
      } else if (this.globalType == 1) {
        //console.log("222", event);
        this.fahtherCheckedEqu = event;
        //全选时要选中所有级别,或取消所有级别
      }
    },
    mergeItems(existingItem, newItem) {
      // 这里假设将两个对象的属性进行合并
      return {
        ...existingItem,
        ...newItem,
      };
    },
    getRowClass(row, index) {
      if (!row.row.IsArray) {
        return "row-expand-cover";
      }
      return "";
      //即改行没有子元素时，添加row-expand-cover类
    },
    titleIcon(data, devIconData) {
      let className = [];
      switch (data.SortIndex) {
        case 1:
          className.push("L-line");
          return className;
        case 2:
          className.push("L-process");
          return className;
        case 3:
          if (devIconData) {
            let res = devIconData.find(
              (m) => String(m.ID) == String(data.StructGuid)
            );
            console.log("res", res);
            if (res) {
              className.push(res.State == 1 ? "green-icon" : "red-icon");
            }
          }
          className.push("L-equipment");
          return className;
        case 4:
          className.push("L-part");
          return className;
        case 5:
          className.push("L-part");
          return className;
        case 6:
          className.push("L-part");
          return className;
        default:
          className.push("L-factory");
          return className;
      }
    },
    selectAll() {
      this.checkedTable = !this.checkedTable;
      this.splite(this.tableData, this.checkedTable);
    },
    /**
     * 处理数据
     */
    splite(data, flag) {
      data.forEach((row) => {
        this.$refs.multipleTable.toggleRowSelection(row, flag);
        if (row.children != undefined) {
          this.splite(row.children);
        }
      });
    },
    UpdateArrayDescript(form) {
      if (form) {
        let table = this.$refs.multipleTable;
        $http.post(form.Url, form).then((res) => {
          if (res.Data) {
            this.$message.success(form.Title + "成功");
            this.expandHandle();
          } else {
            this.$message.error(form.Title + "失败" + res.Message);
          }
        });
      } else {
        this.$message.error("操作监控状态失败");
      }
    },
    addMonitored(form) {
      if (form) {
        if (form.isMonitored) {
          this.$refs.monitorForm.validate((valid) => {
            if (!valid) {
              return;
            } else {
              // this.monitoredForm.scanPeriod =
              //   this.monitoredForm.scanPeriod / 100;
              $http.post(form.Url, form).then((res) => {
                if (res.Data) {
                  //this.processOption = res.Data.pageData

                  this.$message.success(form.Title + "成功");
                  this.addMonitoredVisable = false;
                  if (form.Update) {
                    this.expandHandle();
                  } else {
                    this.selectGlobleVar();
                  }
                } else {
                  this.$confirm(`${res.Message}`, "变量加入监控操作失败", {
                    confirmButtonText: "确定",
                    showCancelButton: false, //是否显示关闭按钮
                    type: "error",
                  });
                }
              });
            }
          });
        } else {
          form.scanPeriod = 0;
          $http.post(form.Url, form).then((res) => {
            if (res.Data) {
              //this.processOption = res.Data.pageData

              this.$message.success(form.Title + "成功");
              this.addMonitoredVisable = false;
              if (form.Update) {
                this.expandHandle();
              } else {
                this.selectGlobleVar();
              }
            } else {
              this.$confirm(`${res.Message}`, "变量取消监控操作失败", {
                confirmButtonText: "确定",
                showCancelButton: false, //是否显示关闭按钮
                type: "error",
              });
            }
          });
        }
      }

      //let table = this.$refs.multipleTable;
      else {
        this.$message.error("操作监控状态失败");
      }
    },
    LoadGlobalVar(tree, treeNode, resolve) {
      //存在子节点就map，否则生成新的子节点，更新的时候加入数据库
      let param = "";
      let objCollection = [];
      let newArray = "";
      for (let i = 0; i < tree.ArrayLength; i++) {
        objCollection.push({
          ID: tree.ID,
          DataType: tree.DataType,
          Alias: tree.Alias + "[" + i + "]",
          IsMonitored: false,
          Description: "",
          ScanPeriod: "",
          InitValue: "",
        });
      }
      if (tree.MonitorInfo) {
        param = JSON.parse(tree.MonitorInfo);

        let newarray = param.map((par) => {
          return {
            ID: tree.ID,
            DataType: tree.DataType,
            Alias: tree.Alias + "[" + par.index + "]",
            IsMonitored: par.isMonitored,
            Description: par.desc,
            ScanPeriod: par.scanPeriod,
            InitValue: par.initValue,
          };
        });
        newArray = objCollection.map((obj) => {
          const newObj = newarray.find((newObj) => newObj.Alias === obj.Alias);
          if (newObj) {
            return newObj;
          } else {
            return obj;
          }
        });
      } else {
        newArray = objCollection;
      }

      resolve(newArray);
    },
    handleSizeChange(val) {
      this.pageSize = val;
      this.selectGlobleVar();
    },
    CurrentChange(val) {
      this.pageNum = val;
      this.selectGlobleVar();
    },
    handleCurrentChange(val) {
      this.sonPageNum = val;
      this.expandHandle();
    },
    deleteProcess(message) {
      if (this.seletNode.StructGuid && this.seletNode.ParentGuid) {
        let param = this.processOption.find(
          (v) => v.name == this.seletNode.DisplayName
        );
        $http
          .post("/EqManage/DeleteProcessInfo", {
            processInfoId: this.seletNode.StructGuid,
            lineId: this.seletNode.ParentGuid,
            processDicId: param ? param.id : 0,
          })
          .then((res) => {
            if (res.Data == true) {
              this.searchOption(this.seletNode, this.treeData);
              this.$message({
                type: "success",
                message: message + "成功",
              });
            } else {
              this.$message({
                type: "error",
                message: message + `失败,${res.Message}`,
              });
            }
          });
      } else {
        return this.$message({
          type: "error",
          message: message + "参数异常",
        });
      }
    },
    addProcess(form) {
      this.$refs.processForm.validate((value) => {
        if (!value) {
          return;
        } else {
          $http
            .post(form.Url, {
              processInfoId: form.Id,
              lineId: form.ParentId,
              processDicId: this.processOption[form.Code].id,
            })
            .then((res) => {
              if (res.Data != null && form.Id == 0) {
                this.seletNode.Children.push({
                  DisplayName: res.Data.Name,
                  SortIndex: 2,
                  StructGuid: res.Data.ID,
                  ParentGuid: form.ParentId,
                  Children: [],
                });
                this.$message.success("添加工序成功");
                this.addProcessVisable = false;
              } else if (res.Data != null && form.Id != 0) {
                this.seletNode.DisplayName = res.Data.Name;
                this.seletNode.StructGuid = res.Data.ID;
                this.seletNode.ParentGuid = form.ParentId;
                //debugger;
                this.searchOption(
                  this.seletNode,
                  this.treeData,
                  this.seletNode
                );
                this.$message.success("修改工序成功");
                this.addProcessVisable = false;
              } else {
                this.$message.error("操作工序失败" + res.Message);
              }
            });
        }
      });
    },
    selectProcess(name, pageNum, pageSize) {
      $http
        .post(`/EQDictionary/GetProcessInfo`, {
          name: name,
          pageSize: pageSize,
          currentPage: pageNum,
        })
        .then((res) => {
          if (res.Data) {
            this.processOption = res.Data.pageData;
          } else {
            this.$message.error("查询工序字典失败", res.Message);
          }
        });
    },
    selectDev(name, pageNum, pageSize) {
      $http
        .post(`/EQDictionary/GetEqCategoryInfo`, {
          name: name,
          pageSize: pageSize,
          currentPage: pageNum,
        })
        .then((res) => {
          if (res.Data) {
            this.deviceOption = res.Data.pageData;
          } else {
            this.$message.error("查询设备字典失败", res.Message);
          }
        });
    },
    Console(param) {
      //console.log(param);
    },
    globalVarOperate(form) {
      this.$refs.globleFormRef.validate((valid) => {
        if (!valid) {
          return this.$message.error("填写数据格式不正确");
        } else {
          $http.post(form.Url, form).then((res) => {
            if (res.Data != null) {
              this.$message({
                type: "success",
                message: form.Title + "成功",
              });
              this.globalType = form.valueType;
              this.globleVarVisable = false;
              this.selectGlobleVar();
            } else {
              this.$message({
                type: "error",
                message: form.Title + `失败,${res.Message}`,
              });
            }
          });
        }
      });
      // this.$refs.globleForm.resetFields(); //重置表单验证
    },
    DeleteglobalVarOperate(form) {
      $http.post(form.Url, form).then((res) => {
        if (res.Data) {
          this.$message({
            type: "success",
            message: form.Title + "成功",
          });
          this.globalType = form.valueType;
          this.selectGlobleVar();
        } else {
          if (res.Message) {
            this.$message({
              type: "error",
              message: res.Message,
            });
          } else {
            this.$message({
              type: "error",
              message: form.Title + "失败",
            });
          }
        }
      });
    },
    dataToPlc(key) {
      return this.variableType.find((m) => m.value == key).name;
    },
    confirmImport(type, isall) {
      this.$confirm(
        type == "all" && isall == 1
          ? "此操作导入设备内部变量, 是否继续?"
          : type == "all" && isall == 2
          ? "此操作导入项目变量, 是否继续?"
          : "此操作导入设备全部配置, 是否继续?",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      )
        .then(() => {
          if (type == "plc") {
            let param = {
              plcId: this.nowNode.data.StructGuid,
              importData: this.importContent,
            };
            $http
              .post(`/EqManage/ImportPlcVariable`, param)
              .then((res) => {
                if (res.Data) {
                  this.importVisable = false;
                  this.$message({
                    type: "success",
                    message: "导入部件变量成功",
                  });
                } else {
                  this.$message({
                    type: "error",
                    message: "导入部件变量失败" + res.Message,
                  });
                }
              })
              .catch((error) => {
                this.$message({
                  type: "error",
                  message: "导入文件格式或内容不正确",
                });
              });
          } else if (type == "eq") {
            let param = {
              eqId: this.seletNode.StructGuid,
              importData: this.importContent,
            };
            $http
              .post(`/EqManage/ImportEqTree`, param)
              .then((res) => {
                if (res.Data) {
                  this.importVisable = false;
                  this.$message({
                    type: "success",
                    message: "导入设备全部配置成功",
                  });
                  this.Refresh();
                } else {
                  this.$message({
                    type: "error",
                    message: "导入设备全部配置失败" + res.Message,
                  });
                }
              })
              .catch((error) => {
                this.$message({
                  type: "error",
                  message: "导入文件格式或内容不正确",
                });
              });
          } else if (type == "all") {
            let param = {
              eqId: this.globalType == 2 ? 0 : this.seletNode.StructGuid,
              importData: this.importContent,
            };
            debugger;
            $http
              .post(`/EqManage/ImportEqVariable`, param)
              .then((res) => {
                if (res.Data) {
                  this.importVisable = false;
                  this.$message({
                    type: "success",
                    message: `${
                      this.globalType == 2 ? "项目变量" : "设备内部变量"
                    }导入成功`,
                  });
                  this.selectGlobleVar();
                } else {
                  this.$message({
                    type: "error",
                    message:
                      `${
                        this.globalType == 2 ? "项目变量" : "设备内部变量"
                      }导入失败` + res.Message,
                  });
                }
              })
              .catch((error) => {
                this.$message({
                  type: "error",
                  message: "导入文件格式或内容不正确",
                });
              });
          }
        })
        .catch((error) => {
          this.$message({
            type: "info",
            message: `已取消导入,${error}`,
          });
        });
    },
    handleExceed(files, fileList) {
      fileList.splice(0, 1, files[0]);
    },
    addfile(files, fileList) {
      if (fileList.length > 1) {
        fileList.splice(0, 1);
      }
      this.fileList = fileList;

      let file = fileList[0];
      let reader = new FileReader();

      if (this.importType == "all") {
         if (file.name.substring(file.name.lastIndexOf(".") + 1) != "xlsx") {
        this.$message.error("变量导入失败，文件格式不正确，请使用xlsx格式文件");
        return;
      }
        reader.readAsBinaryString(file.raw);
        reader.onload = (e) => {
          // 读取文件内容
          const fileString = e.target.result;
          console.log("files", fileString);
          let excel = XLSX.read(fileString, { type: "binary" });
          let sheetname = excel.SheetNames[0];
          let sheet = excel.Sheets[sheetname];
          debugger;
          // delete sheet.A1;
          // 接下来可对文件内容进行处理
          this.importContent = JSON.stringify(
            XLSX.utils.sheet_to_json(sheet, { range: 2 })
          );
          this.importBtn = true;
        };
      } else {
         if (file.name.substring(file.name.lastIndexOf(".") + 1) != "json") {
        this.$message.error("变量导入失败，文件格式不正确，请使用json格式文件");
        return;
      }
        reader.readAsText(file.raw);
        reader.onload = (e) => {
          // 读取文件内容
          const fileString = e.target.result;
          // 接下来可对文件内容进行处理
          this.importContent = fileString;
          this.importBtn = true;
        };
      }
    },
    filterNode(value, data) {
      if (!value) return true;

      return data.DisplayName.indexOf(value) !== -1;
    },
    /**
     * 根据子节点guid获取父节点的guid
     * @param {Guid} Guid
     * @param {树形数组} tree
     */
    getParentKey(Guid, tree) {
      let parentKey;
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i];
        if (node.Children) {
          if (node.Children.some((item) => item.Guid === Guid)) {
            parentKey = node.Guid;
          } else if (this.getParentKey(Guid, node.Children)) {
            parentKey = this.getParentKey(Guid, node.Children);
          }
        }
      }
      return parentKey;
    },

    /**
     * 根据子节点的StructGuid获取父节点name
     * @param {Id} Id
     * @param {树形数组} tree
     */
    getParentName(Id, tree) {
      let parentKey;
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i];
        if (node.Children) {
          if (node.Children.some((item) => item.StructGuid.isEqualTo(Id))) {
            parentKey = node.DisplayName;
          } else if (this.getParentName(Id, node.Children)) {
            parentKey = this.getParentName(Id, node.Children);
          }
        }
      }
      return parentKey;
    },
    findFirstChild(arr) {
      if (arr[0].Children.length == 0) {
        return arr[0];
      }
      return this.findFirstChild(arr[0].Children);
    },
    selectFirst(arr) {
      if (arr[0]) {
        const guid = this.findFirstChild(arr).Guid;
        //console.log(this.findFirstChild(arr));
        this.expandedKey = this.getParentKey(guid, arr);
        //console.log(this.expandedKey);
      }
      if (arr[0].Children[0]) {
        const data = this.findFirstChild(arr);
        this.defaultCheckedKeys = data.Guid;
        this.$nextTick(() => {
          const node = this.$refs.tree.getNode(data.Guid);
          this.$refs.tree.setCurrentKey(String(data.Guid));
          this.clickNode(data, node);
        });
      }
    },
    async Refresh() {
      await $http.get("/Script/GetEqState").then((res) => {
        if (res.Data) {
          this.devIconData = res.Data;
        }
      });
      await $http.get("/EqManage/GetLineProcessDevPLCInfo").then((res) => {
        this.treeData = res.Data;
        if (res.Data[0]) {
          //console.log("res", res.Data);
          //this.expandedKey = res.Data[0].Guid;
          const guid = this.findFirstChild(res.Data).Guid;
          //console.log(this.findFirstChild(res.Data));
          this.expandedKey = this.getParentKey(guid, res.Data);
          //console.log(this.expandedKey);
        }
        if (res.Data[0].Children[0]) {
          //this.$refs.tree.setCheckedKeys([res.Data[0].Children[0].Guid, true]);
          // this.$refs.tree.setCheckedKeys([this.findFirstChild(res.Data).Guid],true);
          // //console.log(this.$refs.tree.setCheckedKeys);
          const data = this.findFirstChild(res.Data);
          this.defaultCheckedKeys = data.Guid;
          this.$nextTick(() => {
            const node = this.$refs.tree.getNode(res.Data[0].Guid);
            this.$refs.tree.setCurrentKey(String(res.Data[0].Guid));
            //console.log("currentnode", node);
            this.clickNode(res.Data[0], node);
          });

          // //console.log(this.defaultCheckedKeys);
          // //console.log(this.$refs.tree.getNode(data));
        }
      });
    },
    /**
     * 树形结构的右键菜单
     * @param {event} event
     * @param {传递给 data 属性的数组中该节点所对应的对象} obj
     * @param {节点对应的 Node} node
     */
    onContextmenu(event, obj, node) {
      // this.expandedKey = obj.Guid;
      this.changeAddressType = "";
      this.rightNode = node;
      this.currentObj = obj;
      this.seletNode = node.data;
      switch (node.data.SortIndex) {
        case 0:
          this.$contextmenu({
            items: [
              {
                label: "添加工厂",
                disabled: this.syncType,
                onClick: () => {
                  (this.dialogVisable = {
                    name: true,
                    code: false,
                    level: false,
                  }),
                    (this.lineForm = {
                      NameLabel: "工厂名称",
                      CodeLabel: "工厂代码名称",
                      Name: "",
                      Id: 0,
                      Code: "",
                      ParentId: this.seletNode.StructGuid,
                      Title: "添加工厂",
                      Message: "添加工厂",
                      Type: 10020,
                      Url: "/EqManage/AddLine",
                    });
                  this.factoryCodeVisable = false;
                  this.addLineVisable = true;
                },
              },
              {
                label: "修改项目",
                onClick: () => {
                  this.factoryForm.name = this.seletNode.DisplayName;
                  this.factoryForm.id = this.seletNode.StructGuid;
                  this.factoryVisable = true;
                },
              },
              {
                label: "切换地址",
                onClick: () => {
                  this.changeAddressType = "";
                  this.changeAddressVisable = true;
                },
              },
            ],
            event,
            x: event.clientX,
            y: event.clientY,
            customClass: "custom-class",
            zIndex: 3,
            minWidth: 230,
          });
          break;
        case 1:
          this.$contextmenu({
            items: [
              {
                label: "添加工序",
                disabled: this.syncType,
                onClick: () => {
                  this.dialogVisable = { name: true, code: true, level: false };
                  this.processForm = {
                    NameLabel: "工序名称",
                    CodeLabel: "工序代码",
                    Name: "",
                    Id: 0,
                    Code: "",
                    ParentId: this.seletNode.StructGuid,
                    Title: "添加工序",
                    Message: "添加工序",
                    Type: 10010,
                    Url: "/EqManage/InsertProcessInfo",
                  };
                  this.addProcessVisable = true;
                },
              },
              {
                label: "修改工厂",
                disabled: this.syncType,
                onClick: () => {
                  this.dialogVisable = {
                    name: true,
                    code: false,
                    level: false,
                  };
                  this.lineForm = {
                    NameLabel: "工厂名称",
                    CodeLabel: "工厂代码名称",
                    Name: this.seletNode.DisplayName,
                    Id: this.seletNode.StructGuid,
                    Code: "",
                    ParentId: this.seletNode.ParentId,
                    Title: "修改工厂",
                    Message: "修改工厂",
                    Type: 10020,
                    Url: "/EqManage/UpdateLineInfo",
                  };
                  this.factoryCodeVisable = false;
                  this.addLineVisable = true;
                },
              },
              {
                label: "删除工厂",
                disabled: this.syncType,
                onClick: () => {
                  this.$confirm("此操作删除工厂, 是否继续?", "提示", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning",
                  })
                    .then(() => this.deleteLine("删除工厂"))
                    .catch(() => {
                      this.$message({
                        type: "info",
                        message: "已取消删除",
                      });
                    });
                },
              },
              {
                label: "切换地址",
                onClick: () => {
                  this.changeAddressType = "";
                  this.changeAddressVisable = true;
                },
              },
            ],
            event,
            x: event.clientX,
            y: event.clientY,
            customClass: "custom-class",
            zIndex: 3,
            minWidth: 230,
          });
          break;
        case 2:
          this.$contextmenu({
            items: [
              {
                label: "添加设备",
                disabled: this.syncType,
                onClick: () => {
                  this.dialogVisable = { name: true, code: true, level: true };
                  this.lineForm = {
                    NameLabel: "设备名称",
                    CodeLabel: "设备编码",
                    Name: "",
                    Id: 0,
                    Code: "",
                    ParentId: this.seletNode.ParentGuid, //工厂id
                    StructGuid: this.seletNode.StructGuid, //工序id
                    Title: "添加设备",
                    Message: "添加设备",
                    Type: 10010,
                    Url: "/EqManage/AddEq",
                    Equipindex: "", //设备分类index
                  };
                  this.factoryCodeVisable = true;
                  this.addLineVisable = true;
                },
              },
              {
                label: "修改工序",
                disabled: this.syncType,
                onClick: () => {
                  this.dialogVisable = { name: true, code: true, level: false };
                  this.processForm = {
                    NameLabel: "工序名称",
                    CodeLabel: "工序代码",
                    Name: "",
                    Id: this.seletNode.StructGuid,
                    Code: this.processOption.findIndex(
                      (v) => v.name == this.seletNode.DisplayName
                    ), //工序字典中的code是option中的index，el-select无法识别long类型
                    ParentId: this.seletNode.ParentGuid,
                    Title: "修改工序",
                    Message: "修改工序",
                    Type: 10010,
                    Url: "/EqManage/UpdateProcessInfo",
                  };
                  this.addProcessVisable = true;
                },
              },

              {
                label: "删除工序",
                disabled: this.syncType,
                onClick: () => {
                  this.$confirm("此操作删除工序, 是否继续?", "提示", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning",
                  }).then(() => this.deleteProcess("删除工序"));
                  // .catch(() => {
                  //   this.$message({
                  //     type: "info",
                  //     message: "已取消删除",
                  //   });
                  // });
                },
              },
              {
                label: "切换地址",
                onClick: () => {
                  this.changeAddressType = "";
                  this.changeAddressVisable = true;
                },
              },
            ],
            event,
            x: event.clientX,
            y: event.clientY,
            customClass: "custom-class",
            zIndex: 3,
            minWidth: 230,
          });
          break;
        case 3:
          {
            let lablemsg =
              this.devIconData.find(
                (m) => String(m.ID) == String(this.seletNode.StructGuid)
              ) &&
              this.devIconData.find(
                (m) => String(m.ID) == String(this.seletNode.StructGuid)
              ).State == 1
                ? "停止设备"
                : "启动设备";
            this.$contextmenu({
              items: [
                {
                  label: "添加部件",
                  onClick: () => {
                    this.plcForm = {
                      Name: "",
                      ID: 0,
                      CommunicationType: 6,
                      ParentId: this.seletNode.StructGuid,
                      EQID: this.seletNode.StructGuid,
                      IP: [],
                      TimeOut: "",
                      Port: [],
                      UserName: "",
                      Password: "",
                      Title: "添加部件",
                      Message: "添加部件",
                      Type: "add",
                      Url: "/EqManage/AddPlc",
                      MaxDisconnection: -1,
                      Site: "",
                      ZeroStart: false,
                      FloatRule: "ABCD",
                      StringReverse: false,
                      MessageConsist: false,
                    };
                    if (this.networkConfig) {
                      //初始化ip和port
                      this.networkConfig.forEach((m) => {
                        m.IP = "";
                        m.Port = "";
                      });
                    }

                    this.plcSettingVisable = true;
                    if (this.$refs.partFormRef)
                      this.$refs.partFormRef.resetFields();
                  },
                },
                {
                  label: "修改设备",
                  disabled: this.syncType,
                  onClick: async () => {
                    let response = {};
                    try {
                      response = await $http.get(
                        `/EqManage/GetEqInfo?id=${this.seletNode.StructGuid}`
                      );
                    } catch (error) {
                      return this.$message.error("请求错误");
                    }

                    //console.log(response.Data);
                    //console.log(this.deviceOption);
                    this.dialogVisable = {
                      name: true,
                      code: false,
                      level: true,
                    };
                    this.lineForm = {
                      Equipindex: this.deviceOption.findIndex(
                        (v) =>
                          String(v.id) == String(response.Data.EQCategoryID)
                      ),
                      NameLabel: "设备名称",
                      CodeLabel: "设备编码",
                      Name: this.seletNode.DisplayName,
                      Id: this.seletNode.StructGuid,
                      Code: response.Data.Code,
                      ParentId: this.rightNode.parent.data.ParentGuid,
                      Title: "修改设备",
                      Message: "修改设备",
                      Type: 10030,
                      Url: "/EqManage/UpdateEqInfo",
                    };
                    this.factoryCodeVisable = true;
                    this.addLineVisable = true;
                  },
                },
                {
                  label: "删除设备",
                  disabled: this.syncType,
                  onClick: () => {
                    this.$confirm("此操作删除设备, 是否继续?", "提示", {
                      confirmButtonText: "确定",
                      cancelButtonText: "取消",
                      type: "warning",
                    })
                      .then(() => this.deleteLine("删除设备"))
                      .catch(() => {
                        this.$message({
                          type: "info",
                          message: "已取消删除",
                        });
                      });
                  },
                },
                {
                  label: "导出设备全部配置",
                  onClick: () => {
                    this.$confirm("此操作导出设备全部配置, 是否继续?", "提示", {
                      confirmButtonText: "确定",
                      cancelButtonText: "取消",
                      type: "warning",
                    })
                      .then(() => {
                        $http
                          .get(
                            `/EqManage/DownLoadEqData?id=${this.seletNode.StructGuid}`,
                            {
                              responseType: "blob",
                            }
                          )
                          .then((res) => {
                            if (res) {
                              const url = window.URL.createObjectURL(
                                new Blob([res], { type: "text/json" })
                              );
                              const link = document.createElement("a");
                              link.href = url;
                              link.setAttribute(
                                "download",
                                `${this.seletNode.DisplayName}.json`
                              );
                              document.body.appendChild(link);
                              link.click();
                            } else {
                              this.$message({
                                type: "error",
                                message: "导出设备内部变量失败",
                              });
                            }
                          });
                      })
                      .catch(() => {
                        this.$message({
                          type: "info",
                          message: "已取消导出",
                        });
                      });
                  },
                },
                {
                  label: "导入设备全部配置",
                  onClick: () => {
                    this.fileList = []; //清空历史导入信息
                    this.$confirm("此操作导入全部设备配置, 是否继续?", "提示", {
                      confirmButtonText: "确定",
                      cancelButtonText: "取消",
                      type: "warning",
                    })
                      .then(() => {
                        this.importType = "eq";
                        this.importVisable = true;
                      })
                      .catch(() => {
                        this.$message({
                          type: "info",
                          message: "已取消导入全部配置",
                        });
                      });
                  },
                },
                {
                  label: lablemsg,

                  onClick: () => {
                    console.log("this", this);
                    this.$confirm(`此操作${lablemsg}, 是否继续?`, "提示", {
                      confirmButtonText: "确定",
                      cancelButtonText: "取消",
                      type: "warning",
                    })
                      .then(() => {
                        $http
                          .get(
                            `/Script/StartOrStopEq?id=${this.seletNode.StructGuid}`
                          )
                          .then((res) => {
                            if (res.Data) {
                              //刷新设备状态
                              $http.get("/Script/GetEqState").then((res) => {
                                if (res.Data) {
                                  this.devIconData = res.Data;
                                }
                              });
                              this.$message({
                                type: "success",
                                message: `${lablemsg}成功`,
                              });
                            } else {
                              this.$message({
                                type: "error",
                                message: `${lablemsg}失败`,
                              });
                            }
                          });
                      })
                      .catch(() => {
                        this.$message({
                          type: "info",
                          message: `已取消${lablemsg}`,
                        });
                      });
                  },
                },
                {
                  label: "切换地址",
                  onClick: () => {
                    this.changeAddressType = "";
                    this.changeAddressVisable = true;
                  },
                },
              ],
              event,
              x: event.clientX,
              y: event.clientY,
              customClass: "custom-class",
              zIndex: 3,
              minWidth: 230,
            });
          }
          break;
        case 4:
          $http
            .get(`/EqManage/GetPlcInfo?id=${this.seletNode.StructGuid}`)
            .then((res) => {
              if (res.Data) {
                var param = JSONBig.parse(res.Data.Connection);
                this.plcmsg = param;

                this.plcForm = {
                  ConnectionId: res.Data.ConnectionId,
                  Name: param.Name,
                  ID: res.Data.ID,
                  CommunicationType: param.CommunicationType,
                  ParentId: 0,
                  IP: param.IP,
                  EQID: res.Data.EQID,
                  TimeOut: param.TimeOut,
                  Port: param.Port,
                  UserName: param.UserName,
                  Password: param.Password,
                  Title: "修改部件",
                  Message: "修改部件",
                  Type: "update",
                  Url: "/EqManage/UpdatePlcInfo",
                  MaxDisconnection: param.MaxDisconnection
                    ? param.MaxDisconnection
                    : -1,
                  Site: param.Site ? param.Site : "",
                  ZeroStart: param.ZeroStart ? param.ZeroStart : false,
                  FloatRule: param.FloatRule ? param.FloatRule : "",
                  StringReverse: param.StringReverse
                    ? param.StringReverse
                    : false,
                  MessageConsist: param.MessageConsist
                    ? param.MessageConsist
                    : false,
                };
                if (param.IP && Array.isArray(param.IP)) {
                  //展开地址信息层级
                  this.networkConfig.forEach((m) => {
                    if (param.IP.find((s) => s.ID == m.id)) {
                      const s = param.IP.find((s) => s.ID == m.id);
                      m.IP = s.IP;
                      m.Port = s.Port;
                    }
                  });
                } else {
                  this.networkConfig.forEach((m) => (m.IP = ""));
                }
                if (param.Port && Array.isArray(param.Port)) {
                  //展开地址信息层级
                  this.networkConfig.forEach((m) => {
                    if (param.Port.find((s) => s.ID == m.id)) {
                      const s = param.Port.find((s) => s.ID == m.id);
                      m.Port = s.Port;
                    }
                  });
                } else {
                  this.networkConfig.forEach((m) => (m.Port = ""));
                }
              }
            });
          //PLC层级展开的时候必须查询PLC详细信息，否则无法进行修改，加入node不可以，刷新时会重置
          this.$contextmenu({
            items: [
              {
                label: "修改部件",
                onClick: () => {
                  this.plcSettingVisable = true;
                },
              },
              {
                label: "删除部件",
                onClick: () => {
                  this.$confirm("此操作删除部件, 是否继续?", "提示", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning",
                  })
                    .then(() => this.deleteLine("删除部件"))
                    .catch(() => {
                      this.$message({
                        type: "info",
                        message: "已取消删除",
                      });
                    });
                },
              },
              {
                label: "切换地址",
                onClick: () => {
                  this.changeAddressType = "";
                  this.changeAddressVisable = true;
                  // $http
                  //   .get(`/EqManage/GetPlcInfo?id=${this.seletNode.StructGuid}`)
                  //   .then((res) => {
                  //     if (res.Data) {
                  //       var param = JSONBig.parse(res.Data.Connection);
                  //       this.plcmsg = param;
                  //       this.connectionId = String(res.Data.ConnectionId);
                  //       //console.log("connectionId", this.ConnectionId);
                  //       this.variableForm.PlcId = param.ID;
                  //       this.changeAddressType = this.connectionId;
                  //       this.changeAddressVisable = true;
                  //     }
                  //   });
                },
              },
            ],
            event,
            x: event.clientX,
            y: event.clientY,
            customClass: "custom-class",
            zIndex: 3,
            minWidth: 230,
          });
          break;
        default:
          break;
      }
      return false;
    },
    // 点击树形节点事件
    clickNode(obj, node) {
      //console.log("obj", obj);
      //console.log("node", node);
      this.expandedKey = obj.Guid;
      this.nowNode = node;
      this.seletNode = node.data;
      this.expandedRowKeys = [];
      //切换树形节点时把数据保存、变量类型和监控状态选项恢复默认
      this.dataTypeId = 0;
      this.isPowerSave = 0;
      this.isMonitor = 0;
      //点击的时候获取设备信息并刷新右侧信息栏
      if (obj.SortIndex == 4) {
        $http.get(`/EqManage/GetPlcInfo?id=${obj.StructGuid}`).then((res) => {
          if (res.Data) {
            var param = JSONBig.parse(res.Data.Connection);
            this.plcmsg = param;
            this.connectionId = String(res.Data.ConnectionId);
            //console.log("connectionId", this.ConnectionId);
            this.variableForm.PlcId = param.ID;
          } else {
            this.$message({
              type: "error",
              message: res.Message,
            });
          }
        });
        //初始化搜索条件
        this.$refs.plcVarTable.reset();
        this.$refs.plcVarTable.selectPlcVar(node.data.StructGuid);
      } else if (obj.SortIndex == 0) {
        this.programName = obj.DisplayName;
        //清空PLC信息，并刷新全局变量参数
        this.plcmsg = {};
        this.globalType = 2;
        this.selectGlobleVar();
        this.varType = 2;
        //查询所有全局变量
      } else if (obj.SortIndex == 3) {
        $http.get(`/EqManage/GetEqInfo?id=${obj.StructGuid}`).then((res) => {
          this.equCode = res.Data.Code;
          let index = this.deviceOption.findIndex(
            (v) => String(v.id) == String(res.Data.EQCategoryID)
          );
          if (index == -1) {
            this.equCategory = "";
          } else {
            this.equCategory = this.deviceOption[index].name;
          }
        });
        this.equName = obj.DisplayName;
        //清空PLC信息，并刷新设备变量参数
        this.plcmsg = {};
        this.varType = 1;
        this.globalType = 1;
        this.selectGlobleVar();
      } else if (obj.SortIndex == 1) {
        this.lineName = obj.DisplayName;
        //清空PLC信息，并刷新设备变量参数
        this.plcmsg = {};
        this.varType = 2;
        this.globalType = 2;
        this.selectGlobleVar();
      } else if (obj.SortIndex == 2) {
        this.processName = obj.DisplayName;
        this.plcmsg = {};
        this.varType = 2;
        this.globalType = 2;
        this.selectGlobleVar();
      }
    },
    addLine(form) {
      this.$refs.lineForm.validate((value) => {
        if (!value) {
          return;
        } else {
          if (
            //10020添加工厂  10010添加设备 10030 修改设备
            form.Type == 10020 &&
            form.Name == ""
          )
            return this.$message({
              type: "error",
              message: this.lineForm.Message + "信息不可为空",
            });
          if (
            form.Type == 10010 &&
            (form.Name == "" || form.Code == "" || form.Equipindex === "")
          )
            return this.$message({
              type: "error",
              message: this.lineForm.Message + "信息不可为空",
            });
          if (form.Type == 10030 && form.Name == "")
            return this.$message({
              type: "error",
              message: this.lineForm.Message + "信息不可为空",
            });
          let param = {};
          if (form.Type == 10010 || form.Type == 10030) {
            param = {
              Name: form.Name,
              Id: form.Id,
              Code: form.Code,
              LineId: form.ParentId,
              ProcessInfoID: form.StructGuid,
              EQCategoryID: this.deviceOption[form.Equipindex].id,
            };
          } else if (form.Type == 10020) {
            param = {
              Name: form.Name,
              Id: form.Id,
              Code: form.Code,
              ParentId: form.ParentId,
            };
          }
          $http
            .post(this.lineForm.Url, param)
            .then((res) => {
              if (res.Data != null) {
                switch (form.Type) {
                  case 10020: //添加工厂
                    this.seletNode.Children.push({
                      DisplayName: res.Data.Name,
                      SortIndex: 1,
                      StructGuid: res.Data.ID,
                      Children: [],
                    });
                    break;
                  case 10010: //添加设备
                    this.seletNode.Children.push({
                      DisplayName: res.Data.Name,
                      SortIndex: 3,
                      StructGuid: res.Data.ID,
                      Children: [],
                    });

                    break;
                  case 10030: //工厂重命名
                    this.seletNode.DisplayName = res.Data.Name;
                    this.searchOption(
                      this.seletNode,
                      this.treeData,
                      this.seletNode
                    );
                    break;
                  default:
                    break;
                }

                this.$message({
                  type: "success",
                  message: this.lineForm.Message + "成功",
                });
                //this.Refresh();
                this.clickNode(this.currentObj, this.rightNode);
                this.addLineVisable = false;
              } else {
                this.$message({
                  type: "error",
                  message: this.lineForm.Message + `失败,${res.Message}`,
                });
              }
            })
            .catch((error) => {
              this.$message({
                type: "error",
                message: this.lineForm.Message + `失败,${error.Message}`,
              });
            });
        }
      });
    },
    deleteLine(message) {
      if (this.seletNode.StructGuid && this.seletNode.SortIndex) {
        console.log(
          `id = ${this.seletNode.StructGuid} & type=${this.seletNode.SortIndex}`
        );
        this.selectFirst(this.treeData);
        $http

          .get(
            `/EqManage/DeleteLineEqPlc?id=${this.seletNode.StructGuid}&type=${this.seletNode.SortIndex}`
          )
          .then((res) => {
            if (res.Data == true) {
              this.searchOption(this.seletNode, this.treeData);
              this.$message({
                type: "success",
                message: message + "成功",
              });
            } else {
              this.$message({
                type: "error",
                message: message + "失败," + res.Message,
              });
            }
          });
      } else {
        return this.$message({
          type: "error",
          message: message + "参数异常",
        });
      }
    },
    selectGlobleVar() {
      let param = {
        pageSize: this.pageSize,
        currentPage: this.pageNum,
        eqId: this.globalType == 1 ? this.nowNode.data.StructGuid : 0, //全局变量不需要设备id
        alias: this.alias,
        isPersistence: this.isPowerSave,
        dataTypeId: this.dataTypeId,
        isMonitored: this.isMonitor,
        isEqGol: this.globalType,
      };

      let isDifferent = false;

      for (let key in param) {
        if (
          key !== "currentPage" &&
          JSON.stringify(param[key]) !==
            JSON.stringify(this.searchConditionLast[key])
        ) {
          isDifferent = true;
          break;
        }
      }

      if (isDifferent) {
        this.pageNum = 1;
        param.currentPage = 1;
      }

      this.searchConditionLast = param;

      //查询所有全局变量
      $http.post("/EqManage/GetEqGlobalVar", param).then((res) => {
        if (res.Data != null) {
          this.globalTable = res.Data.BizData;
          this.total = res.Data.TotalCount;
        } else {
          this.$message({
            type: "error",
            message: "查询变量失败",
          });
        }
      });
    },
    refreshRight() {
      this.clickNode(this.currentObj, this.rightNode);
    },
    // 添加部件弹窗确定
    operatePlc(form) {
      this.$refs.partFormRef.validate((valid) => {
        if (!valid) {
          return this.$message.error("填写数据格式不正确");
        } else {
          //console.log(form);
          //console.log(this.networkConfig);
          const IP = this.networkConfig
            .filter((item) => item.IP)
            .map((item) => ({
              ID: item.id,
              // IP: form.CommunicationType == 6 ? "opc.tcp://" + item.IP : item.IP,
              IP: item.IP,
            }));
          const Port = this.networkConfig
            .filter((item) => item.Port)
            .map(({ id: ID, Port }) => ({ ID, Port }));
          // form.IP = JSON.stringify(IP);
          // form.Port = JSON.stringify(Port);
          form.IP = IP;
          form.Port = Port;
          form.ConnectionId =
            form.Type == "add" ? this.networkConfig[0].id : form.ConnectionId;
          //console.log('form',form);
          form.Site = form.Site === "" ? 0 : form.Site;
          if (form.Type == "update") {
            //需判断当前连接地址是否被清空
            debugger;
            let name = this.networkConfig.filter(
              (item) => String(item["id"]) == String(form.ConnectionId)
            )[0].name;
            let result = this.networkConfig.filter(
              (item) =>
                String(item["id"]) == String(form.ConnectionId) &&
                (item["IP"] == "" || item["Port"] == "")
            );
            if (result.length > 0) {
              return this.$message({
                type: "error",
                message: `目前连接地址是${name},修改失败`,
              });
            }
          }
          $http.post(this.plcForm.Url, form).then((res) => {
            if (res.Data != null) {
              if (form.Type == "add") {
                this.seletNode.Children.push({
                  DisplayName: res.Data.Name,
                  SortIndex: 4,
                  StructGuid: res.Data.ID,
                });
              } else if (form.Type == "update") {
                this.seletNode.DisplayName = res.Data.Name;
                this.searchOption(
                  this.seletNode,
                  this.treeData,
                  this.seletNode
                );
              } else {
                return;
              }

              this.$message({
                type: "success",
                message: this.plcForm.Message + "成功",
              });
              this.plcSettingVisable = false;
              this.refreshRight();
            } else {
              this.$message({
                type: "error",
                message: res.Message,
              });
            }
          });
        }
      });
    },
    //  递归查找操作的节点，在父节点的children中删除
    searchOption(option, arr, obj) {
      //首先循环arr最外层数据

      for (let s = 0; s < arr.length; s++) {
        //如果匹配到了arr最外层中的我需要删除的数据
        if (arr[s].StructGuid === option.StructGuid) {
          //删除即删除即可
          if (obj) {
            arr.splice(s, 1, obj);
          } else {
            arr.splice(s, 1);
          }
          break;
        } else if (arr[s].Children && arr[s].Children.length > 0) {
          // 递归条件
          this.searchOption(option, arr[s].Children, obj);
        } else {
          continue;
        }
      }
    },
    // operateDev(title, name, type) {},
    addPlcVariable(form) {
      $http.post(form.Url, form).then((res) => {
        if (res.Data != null) {
          this.selectVariableModel.Url = "/EqManage/GetPlcVar";
          this.selectVariableModel.PlcId = form.PlcID;
          this.selectVariableModel.Message = "查询变量";
          this.selectPlcVariable(this.selectVariableModel);
          this.this.$message({
            type: "success",
            message: form.Title + "成功",
          });
        } else {
          this.$message({
            type: "error",
            message: form.Title + "失败",
          });
        }
      });
    },
    async selectPlcVariable(model) {
      await $http.post(model.Url, model).then((res) => {
        if (res.Data != null) {
          this.tableData = res.Data;
        } else {
          this.tableData = null;
          this.$message({
            type: "error",
            message: model.Message + "失败",
          });
        }
      });
    },
    changeVariableLength(event) {
      this.variableForm.ArrayLength = 0;
    },

    deletePlcVar(obj) {
      this.$confirm("此操作删除部件变量, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() =>
        $http.get(`/EqManage/DeleteVar?id=${obj.ID}`).then((res) => {
          if (res.Data) {
            this.selectVariableModel.Url = "/EqManage/GetPlcVar";
            this.selectVariableModel.PlcId = obj.PlcID;
            this.selectVariableModel.Message = "查询变量";
            this.selectVariableModel.IsMonitored = 0;
            this.selectPlcVariable(this.selectVariableModel);
          } else {
            this.$message({
              type: "info",
              message: res.Message,
            });
          }
          //刷新变量栏目
        })
      );
    },

    openCSV(id, name) {
      //console.log(this.nowNode);
      if (this.fahtherCheckedAll.length > 0 && this.globalType == 2) {
        this.$confirm("此操作导出项目变量, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            $http
              .post(
                `/EqManage/BatchDownEqData`,
                JSON.parse(JSON.stringify(this.fahtherCheckedAll))
              )
              .then((res) => {
                if (res) {
                  const url = window.URL.createObjectURL(
                    new Blob([res], { type: "text/json" })
                  );
                  const link = document.createElement("a");
                  link.href = url;
                  link.setAttribute("download", `${name}全局.json`);
                  document.body.appendChild(link);
                  link.click();
                } else {
                  this.$message({
                    type: "error",
                    message: "导出项目变量失败",
                  });
                }
              });
          })
          .catch(() => {
            this.$message({
              type: "info",
              message: "已取消导出",
            });
          });
      } else if (this.fahtherCheckedEqu.length > 0 && this.globalType == 1) {
        this.$confirm("此操作导出设备内部变量, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            $http
              .post(
                `/EqManage/BatchDownEqData`,
                JSON.parse(JSON.stringify(this.fahtherCheckedEqu))
              )
              .then((res) => {
                if (res) {
                  const url = window.URL.createObjectURL(
                    new Blob([res], { type: "application/vnd.ms-excel" })
                  );
                  const link = document.createElement("a");
                  link.href = url;
                  link.setAttribute("download", `${name}-设备内部变量.xlsx`);
                  document.body.appendChild(link);
                  link.click();
                } else {
                  this.$message({
                    type: "error",
                    message: "导出设备内部变量失败",
                  });
                }
              });
          })
          .catch(() => {
            this.$message({
              type: "info",
              message: "已取消导出",
            });
          });
      } else {
        this.$confirm("此操作导出设备内部变量, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            $http
              .get(
                `/EqManage/DownLoadEqVarData?id=${
                  this.globalType == 1 ? id : 0
                }`,
                {
                  responseType: "blob",
                }
              )
              .then((res) => {
                if (res) {
                  console.log("testblob", res);
                  const url = window.URL.createObjectURL(
                    new Blob([res], { type: "application/vnd.ms-excel" })
                  );
                  const link = document.createElement("a");
                  link.href = url;
                  link.setAttribute(
                    "download",
                    `${name}${this.varType == 2 ? "项目" : "设备"}.xlsx`
                  );
                  document.body.appendChild(link);
                  link.click();
                } else {
                  this.$message({
                    type: "error",
                    message: "导出设备内部变量失败",
                  });
                }
              });
          })
          .catch(() => {
            this.$message({
              type: "info",
              message: "已取消导出",
            });
          });
      }
    },

    exportCSV(title) {
      const data = this.tableData;
      if (!data || data.length <= 0) {
        this.$message({
          type: "error",
          message: "未加载变量数据,不可导出",
        });
      }
      const csv = this.convertToCSV(data);
      const filename = title + ".csv";
      const blob = new Blob(["\uFEFF" + csv], {
        type: "text/csv;charset=utf-8;",
      });
      if (navigator.msSaveBlob) {
        navigator.msSaveBlob(blob, filename);
      } else {
        const link = document.createElement("a");
        if (link.download !== undefined) {
          const url = URL.createObjectURL(blob);
          link.setAttribute("href", url);
          link.setAttribute("download", filename);
          link.style.visibility = "hidden";
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        }
      }
    },
    convertToCSV(data) {
      const headers = Object.keys(data[0]);
      const rows = data.map((item) => {
        return headers
          .map((header) => {
            return item[header];
          })
          .join(",");
      });
      return headers.join(",") + "\n" + rows.join("\n");
    },
  },
};
</script>
<style>
.el-descriptions-item__content {
  display: flex !important;
  justify-content: space-between !important;
}

.red-icon {
  background-color: #f56c6c;
}
.green-icon {
  background-color: #409eff;
}

.row-expand-cover .el-table__expand-column .cell {
  /* visibility: hidden; */
  display: none;
}
.addressmsg {
  text-align: center;
  margin-top: 25px;
}
.import-icon {
  color: #606266;
  font-size: 14px;
}
.el-tree-node.is-expanded > .el-tree-node__children {
  display: inline;
}
</style>
